Merge pull request #151 from tiqi-group/breaking/client_arguments

Breaking: changing allowed client arguments
This commit is contained in:
Mose Müller 2024-08-13 07:04:10 +02:00 committed by GitHub
commit 9aad9dfbc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 37 additions and 22 deletions

View File

@ -170,7 +170,8 @@ import pydase
# Replace the hostname and port with the IP address and the port of the machine where
# the service is running, respectively
client_proxy = pydase.Client(hostname="<ip_addr>", port=8001).proxy
client_proxy = pydase.Client(url="ws://<ip_addr>:<service_port>").proxy
# client_proxy = pydase.Client(url="wss://your-domain.ch").proxy # if your service uses ssl-encryption
# After the connection, interact with the service attributes as if they were local
client_proxy.voltage = 5.0
@ -195,7 +196,8 @@ import pydase
class MyService(pydase.DataService):
# Initialize the client without blocking the constructor
proxy = pydase.Client(hostname="<ip_addr>", port=8001, block_until_connected=False).proxy
proxy = pydase.Client(url="ws://<ip_addr>:<service_port>", block_until_connected=False).proxy
# proxy = pydase.Client(url="wss://your-domain.ch", block_until_connected=False).proxy # communicating with ssl-encrypted service
if __name__ == "__main__":
service = MyService()

View File

@ -5,9 +5,10 @@ You can connect to the service using the `pydase.Client`. Below is an example of
```python
import pydase
# Replace the hostname and port with the IP address and the port of the machine
# where the service is running, respectively
client_proxy = pydase.Client(hostname="<ip_addr>", port=8001).proxy
# Replace the hostname and port with the IP address and the port of the machine where
# the service is running, respectively
client_proxy = pydase.Client(url="ws://<ip_addr>:<service_port>").proxy
# client_proxy = pydase.Client(url="wss://your-domain.ch").proxy # if your service uses ssl-encryption
# Interact with the service attributes as if they were local
client_proxy.voltage = 5.0
@ -32,7 +33,8 @@ import pydase
class MyService(pydase.DataService):
# Initialize the client without blocking the constructor
proxy = pydase.Client(hostname="<ip_addr>", port=8001, block_until_connected=False).proxy
proxy = pydase.Client(url="ws://<ip_addr>:<service_port>", block_until_connected=False).proxy
# proxy = pydase.Client(url="wss://your-domain.ch", block_until_connected=False).proxy # communicating with ssl-encrypted service
if __name__ == "__main__":
service = MyService()

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "pydase"
version = "0.8.5"
version = "0.9.0"
description = "A flexible and robust Python library for creating, managing, and interacting with data services, with built-in support for web and RPC servers, and customizable features for diverse use cases."
authors = ["Mose Mueller <mosmuell@ethz.ch>"]
readme = "README.md"

View File

@ -80,12 +80,12 @@ class Client:
if it were local.
Args:
hostname (str):
Hostname of the exposed service this client attempts to connect to.
Default is "localhost".
port (int):
Port of the exposed service this client attempts to connect on.
Default is 8001.
url (str):
The URL of the pydase Socket.IO server. This should always contain the
protocol and the hostname.
Examples:
- wss://my-service.example.com # for secure connections, use wss
- ws://localhost:8001
block_until_connected (bool):
If set to True, the constructor will block until the connection to the
service has been established. This is useful for ensuring the client is
@ -94,12 +94,11 @@ class Client:
def __init__(
self,
hostname: str,
port: int,
*,
url: str,
block_until_connected: bool = True,
):
self._hostname = hostname
self._port = port
self._url = url
self._sio = socketio.AsyncClient()
self._loop = asyncio.new_event_loop()
self.proxy = ProxyClass(sio_client=self._sio, loop=self._loop)
@ -107,29 +106,41 @@ class Client:
target=asyncio_loop_thread, args=(self._loop,), daemon=True
)
self._thread.start()
self.connect(block_until_connected=block_until_connected)
def connect(self, block_until_connected: bool = True) -> None:
connection_future = asyncio.run_coroutine_threadsafe(
self._connect(), self._loop
)
if block_until_connected:
connection_future.result()
def disconnect(self) -> None:
connection_future = asyncio.run_coroutine_threadsafe(
self._disconnect(), self._loop
)
connection_future.result()
async def _connect(self) -> None:
logger.debug("Connecting to server '%s:%s' ...", self._hostname, self._port)
logger.debug("Connecting to server '%s' ...", self._url)
await self._setup_events()
await self._sio.connect(
f"ws://{self._hostname}:{self._port}",
self._url,
socketio_path="/ws/socket.io",
transports=["websocket"],
retry=True,
)
async def _disconnect(self) -> None:
await self._sio.disconnect()
async def _setup_events(self) -> None:
self._sio.on("connect", self._handle_connect)
self._sio.on("disconnect", self._handle_disconnect)
self._sio.on("notify", self._handle_update)
async def _handle_connect(self) -> None:
logger.debug("Connected to '%s:%s' ...", self._hostname, self._port)
logger.debug("Connected to '%s' ...", self._url)
serialized_object = cast(
SerializedDataService, await self._sio.call("service_serialization")
)
@ -141,7 +152,7 @@ class Client:
self.proxy._connected = True
async def _handle_disconnect(self) -> None:
logger.debug("Disconnected from '%s:%s' ...", self._hostname, self._port)
logger.debug("Disconnected from '%s' ...", self._url)
self.proxy._connected = False
async def _handle_update(self, data: NotifyDict) -> None:

View File

@ -45,7 +45,7 @@ def pydase_client() -> Generator[pydase.Client, None, Any]:
thread = threading.Thread(target=server.run, daemon=True)
thread.start()
client = pydase.Client(hostname="localhost", port=9999)
client = pydase.Client(url="ws://localhost:9999")
yield client