updates sio events in web server

This commit is contained in:
Mose Müller 2024-03-27 09:29:29 +01:00
parent 27f22d472d
commit 4db15f2fe8

View File

@ -2,14 +2,15 @@ import asyncio
import logging
from typing import Any, TypedDict
import click
import socketio # type: ignore[import-untyped]
from pydase.data_service.data_service import process_callable_attribute
from pydase.data_service.data_service_observer import DataServiceObserver
from pydase.data_service.state_manager import StateManager
from pydase.utils.deserializer import Deserializer, loads
from pydase.utils.helpers import get_object_attr_from_path_list
from pydase.utils.logging import SocketIOHandler
from pydase.utils.serializer import SerializedObject
from pydase.utils.serializer import SerializedObject, dump
logger = logging.getLogger(__name__)
@ -21,26 +22,17 @@ class UpdateDict(TypedDict):
Attributes:
----------
name : str
The name of the attribute to be updated in the DataService instance.
If the attribute is part of a nested structure, this would be the name of the
attribute in the last nested object. For example, for an attribute access path
'attr1.list_attr[0].attr2', 'attr2' would be the name.
parent_path : str
The access path for the parent object of the attribute to be updated. This is
used to construct the full access path for the attribute. For example, for an
attribute access path 'attr1.list_attr[0].attr2', 'attr1.list_attr[0]' would be
the parent_path.
value : Any
The new value to be assigned to the attribute. The type of this value should
match the type of the attribute to be updated.
value : SerializedObject
The serialized new value to be assigned to the attribute.
"""
name: str
parent_path: str
value: Any
value: SerializedObject
class TriggerMethodDict(TypedDict):
access_path: str
args: SerializedObject
kwargs: SerializedObject
class RunMethodDict(TypedDict):
@ -120,23 +112,46 @@ def setup_sio_server(
def setup_sio_events(sio: socketio.AsyncServer, state_manager: StateManager) -> None:
@sio.event # type: ignore
async def connect(sid: str, environ: Any) -> None:
logging.debug("Client [%s] connected", click.style(str(sid), fg="cyan"))
await sio.emit("class_structure", state_manager.cache, to=sid)
@sio.event # type: ignore
async def disconnect(sid: str) -> None:
logging.debug("Client [%s] disconnected", click.style(str(sid), fg="cyan"))
@sio.event
def set_attribute(sid: str, data: UpdateDict) -> Any:
logger.debug("Received frontend update: %s", data)
parent_path = data["parent_path"].split(".")
path_list = [element for element in parent_path if element] + [data["name"]]
path = ".".join(path_list)
async def update_value(sid: str, data: UpdateDict) -> None:
logger.debug(data)
path = data["value"]["full_access_path"]
# this should probably happen within the following function call -> can also
# look at the current type of the attribute at "path"
new_value = loads(data["value"])
return state_manager.set_service_attribute_value_by_path(
path=path, value=data["value"]
path=path, value=new_value
)
@sio.event
def run_method(sid: str, data: RunMethodDict) -> Any:
logger.debug("Running method: %s", data)
parent_path = data["parent_path"].split(".")
path_list = [element for element in parent_path if element] + [data["name"]]
method = get_object_attr_from_path_list(state_manager.service, path_list)
return process_callable_attribute(method, data["kwargs"])
async def get_value(sid: str, access_path: str) -> SerializedObject:
return state_manager._data_service_cache.get_value_dict_from_cache(access_path)
@sio.event
async def trigger_method(sid: str, data: TriggerMethodDict) -> Any:
logger.info(data)
try:
method = get_object_attr_from_path_list(
state_manager.service, data["access_path"].split(".")
)
args = Deserializer.deserialize(data["args"])
kwargs: dict[str, Any] = Deserializer.deserialize(data["kwargs"])
return dump(method(*args, **kwargs))
except Exception as e:
logger.error(e)
return dump(e)
def setup_logging_handler(sio: socketio.AsyncServer) -> None: