Service¤
To implement your own Service, just inherit from the Service class, create the methods/attributes that you want your Service to provide and then run your script.
Warning
Your subclass cannot have method/attribute names that are the same as those found in the Link class, otherwise a request will not be sent to your Service because the Link instance will handle the method call.
import asyncio
from msl.network import Service
class Camera(Service):
def __init__(self) -> None:
"""Allows for a camera to be controllable via the network."""
super().__init__()
self._camera = ... # (1)!
self.version: str = "1.3" # (2)!
def get_resolution(self) -> tuple[int, int]:
"""Get the image resolution."""
return self._camera.resolution
def set_resolution(self, width: int, height: int) -> None:
"""Set the image resolution."""
self._camera.resolution = (width, height)
async def stream(self) -> None:
"""This coroutine is also run in the event loop."""
while True:
self.publish(self._camera.capture())
await asyncio.sleep(1)
if __name__ == "__main__":
c = Camera()
c.add_tasks(c.stream()) # (3)!
c.connect() # (4)!
- Access the camera interface.
- A Client can also send a request for an attribute value, not just callable methods.
- Add the
streammethod to the event loop of the Service to publish images every second. - Connect to the Broker. Runs the event loop forever.
Service
¤
Service(
*,
name: str | None = None,
host: str = "127.0.0.1",
port: int = BROKER_PORT,
flag: Flag = PICKLE,
curve: AuthCurve | None = None,
plain: AuthPlain | None = None,
xsub_port: int | None = None,
ignore_attributes: str | Iterable[str] | None = None
)
Base class for a Service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
None
|
|
host
|
str
|
The hostname (or IP address) that the Broker is running on. |
'127.0.0.1'
|
port
|
int
|
The network port that the Broker is running on. |
BROKER_PORT
|
flag
|
Flag
|
The serialisation and compression algorithms to apply to a reply before sending the message. |
PICKLE
|
curve
|
AuthCurve | None
|
The CURVE authentication to use. |
None
|
plain
|
AuthPlain | None
|
The PLAIN authentication to use. |
None
|
xsub_port
|
int | None
|
The port on the Broker that is subscribed to publications.
Typically, this value is |
None
|
ignore_attributes
|
str | Iterable[str] | None
|
The names of the attributes to not include in the signatures map. See ignore_attributes for more details. |
None
|
Source code in src/msl/network/service.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
flag
instance-attribute
¤
flag: Flag = flag
The serialisation and compression algorithms to apply to a reply or publication before sending the message.
add_tasks
¤
add_tasks(*aws: Awaitable[None]) -> None
Add tasks to run in the event loop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aws
|
Awaitable[None]
|
Awaitables that will run in the event loop. |
()
|
Source code in src/msl/network/service.py
116 117 118 119 120 121 122 | |
before_disconnect
¤
before_disconnect() -> None
Called immediately before the Service disconnects from the Broker.
Override this method to, for example, clean up resources that are used by the Service.
Source code in src/msl/network/service.py
124 125 126 127 128 | |
connect
¤
connect() -> None
Connect (or reconnect) to the Broker.
Calling this method will run the event loop until all tasks have completed.
Source code in src/msl/network/service.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
disconnect
¤
disconnect() -> None
Disconnect from the Broker.
Source code in src/msl/network/service.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
flag_at
¤
Use as a context manager to temporarily change the flag value.
Example
from msl.network import Flag, Service
class Camera(Service):
def __init__(self) -> None:
"""By default, use JSON to serialise all replies (no compression)."""
super().__init__(flag=Flag.JSON)
self._camera = ... # Access the camera interface
def get_resolution(self) -> tuple[int, int]:
"""Returns the (width, height) of a captured image.
The reply is serialised using JSON without compression.
"""
return self._camera.resolution
def capture(self) -> bytes:
"""Capture an image and return the image bytes.
For this method, compressed bytes without serialisation is returned.
"""
with self.flag_at(Flag.ZLIB): # (1)!
return self._camera.capture()
- Temporarily change the serialisation and compression algorithms to send the reply.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flag
|
Flag
|
The temporary flag to use while within the context. Once the context exits, the value is reset to the original value. |
required |
Source code in src/msl/network/service.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | |
ignore_attributes
¤
ignore_attributes(*names: str) -> None
Ignore attributes from being added to the signatures map.
There are a few reasons why you may want to call this method:
- If you do not want an attribute to be made publicly known that it exists; however, a Client can still receive a reply for an ignored attribute that it requested.
- If warnings are logged indicating that the signature of an attribute cannot be found and you prefer not to see the warnings (this could result from a Service using multiple inheritance).
Private attributes (i.e., attribute names that start with an underscore) are automatically ignored and if a Client sends a request for a private attribute it will receive an error message as the reply.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
names
|
str
|
The names of the attributes to exclude from the signatures map. |
()
|
Source code in src/msl/network/service.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
publish
¤
Publish a value to all subscribers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
The value to publish. |
required |
flag
|
Flag | None
|
The flag to use to convert the |
None
|
Source code in src/msl/network/service.py
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
signatures
¤
Returns the function signatures that the Service provides.
For example,
{
"get_resolution": "() -> tuple[int, int]",
"set_resolution": "(width: int, height: int) -> None",
"stream": "() -> None",
"version": "() -> str"
}
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A mapping between the function (attribute) name and the function signature (attribute type). |
Source code in src/msl/network/service.py
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |