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