mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-03 20:30:40 +02:00
adds support for datetime serialization
This commit is contained in:
parent
8afee54c51
commit
cf0780b2ca
@ -1,16 +1,22 @@
|
||||
import enum
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Any, NoReturn, cast
|
||||
|
||||
import pydase
|
||||
import pydase.components
|
||||
import pydase.units as u
|
||||
from pydase.utils.helpers import get_component_classes
|
||||
from pydase.utils.serialization.types import SerializedObject
|
||||
from pydase.utils.serialization.types import (
|
||||
SerializedDatetime,
|
||||
SerializedException,
|
||||
SerializedObject,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -33,6 +39,7 @@ class Deserializer:
|
||||
"dict": cls.deserialize_dict,
|
||||
"method": cls.deserialize_method,
|
||||
"Exception": cls.deserialize_exception,
|
||||
"datetime": cls.deserialize_datetime,
|
||||
}
|
||||
|
||||
# First go through handled types (as ColouredEnum is also within the components)
|
||||
@ -57,6 +64,10 @@ class Deserializer:
|
||||
def deserialize_quantity(cls, serialized_object: SerializedObject) -> Any:
|
||||
return u.convert_to_quantity(serialized_object["value"]) # type: ignore
|
||||
|
||||
@classmethod
|
||||
def deserialize_datetime(cls, serialized_object: SerializedDatetime) -> datetime:
|
||||
return datetime.fromisoformat(serialized_object["value"])
|
||||
|
||||
@classmethod
|
||||
def deserialize_enum(
|
||||
cls,
|
||||
@ -88,11 +99,11 @@ class Deserializer:
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def deserialize_exception(cls, serialized_object: SerializedObject) -> NoReturn:
|
||||
def deserialize_exception(cls, serialized_object: SerializedException) -> NoReturn:
|
||||
import builtins
|
||||
|
||||
try:
|
||||
exception = getattr(builtins, serialized_object["name"]) # type: ignore
|
||||
exception = getattr(builtins, serialized_object["name"])
|
||||
except AttributeError:
|
||||
exception = type(serialized_object["name"], (Exception,), {}) # type: ignore
|
||||
raise exception(serialized_object["value"])
|
||||
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import inspect
|
||||
import logging
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||
|
||||
@ -21,6 +22,7 @@ from pydase.utils.serialization.types import (
|
||||
DataServiceTypes,
|
||||
SerializedBool,
|
||||
SerializedDataService,
|
||||
SerializedDatetime,
|
||||
SerializedDict,
|
||||
SerializedEnum,
|
||||
SerializedException,
|
||||
@ -61,6 +63,9 @@ class Serializer:
|
||||
if isinstance(obj, Exception):
|
||||
result = cls._serialize_exception(obj)
|
||||
|
||||
elif isinstance(obj, datetime):
|
||||
result = cls._serialize_datetime(obj, access_path=access_path)
|
||||
|
||||
elif isinstance(obj, AbstractDataService):
|
||||
result = cls._serialize_data_service(obj, access_path=access_path)
|
||||
|
||||
@ -113,6 +118,16 @@ class Serializer:
|
||||
"value": obj,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _serialize_datetime(cls, obj: datetime, access_path: str) -> SerializedDatetime:
|
||||
return {
|
||||
"type": "datetime",
|
||||
"value": str(obj),
|
||||
"doc": None,
|
||||
"full_access_path": access_path,
|
||||
"readonly": True,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _serialize_exception(cls, obj: Exception) -> SerializedException:
|
||||
return {
|
||||
|
@ -45,6 +45,11 @@ class SerializedString(SerializedObjectBase):
|
||||
type: Literal["str"]
|
||||
|
||||
|
||||
class SerializedDatetime(SerializedObjectBase):
|
||||
type: Literal["datetime"]
|
||||
value: str
|
||||
|
||||
|
||||
class SerializedEnum(SerializedObjectBase):
|
||||
name: str
|
||||
value: str
|
||||
@ -107,6 +112,7 @@ SerializedObject = (
|
||||
| SerializedFloat
|
||||
| SerializedInteger
|
||||
| SerializedString
|
||||
| SerializedDatetime
|
||||
| SerializedList
|
||||
| SerializedDict
|
||||
| SerializedNoneType
|
||||
|
@ -1,4 +1,5 @@
|
||||
import enum
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pydase.components
|
||||
@ -137,6 +138,16 @@ def test_loads_primitive_types(obj: Any, obj_serialization: SerializedObject) ->
|
||||
"name": "MyService",
|
||||
},
|
||||
),
|
||||
(
|
||||
datetime.fromisoformat("2024-07-09 15:37:08.249845"),
|
||||
{
|
||||
"full_access_path": "",
|
||||
"type": "datetime",
|
||||
"value": "2024-07-09 15:37:08.249845",
|
||||
"readonly": True,
|
||||
"doc": None,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_loads_advanced_types(obj: Any, obj_serialization: SerializedObject) -> None:
|
||||
|
@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import enum
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any, ClassVar
|
||||
|
||||
@ -92,6 +93,16 @@ service_instance = ServiceClass()
|
||||
"doc": None,
|
||||
},
|
||||
),
|
||||
(
|
||||
datetime.fromisoformat("2024-07-09 15:37:08.249845"),
|
||||
{
|
||||
"full_access_path": "",
|
||||
"type": "datetime",
|
||||
"value": "2024-07-09 15:37:08.249845",
|
||||
"readonly": True,
|
||||
"doc": None,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_dump(test_input: Any, expected: dict[str, Any]) -> None:
|
||||
@ -476,8 +487,7 @@ def test_derived_data_service_serialization() -> None:
|
||||
def name(self, value: str) -> None:
|
||||
self._name = value
|
||||
|
||||
class DerivedService(BaseService):
|
||||
...
|
||||
class DerivedService(BaseService): ...
|
||||
|
||||
base_service_serialization = dump(BaseService())
|
||||
derived_service_serialization = dump(DerivedService())
|
||||
|
Loading…
x
Reference in New Issue
Block a user