Skip to content

Commit ec2c343

Browse files
authored
add port and adapters for serializers (#178)
* refactor * fix unknown types * update import statements in server folder * fix import statements and bugs * fix conftest
1 parent 2a7f3ec commit ec2c343

28 files changed

Lines changed: 753 additions & 612 deletions

.github/workflows/ci-pipeline.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,14 @@ jobs:
8080
run: |
8181
source .venv/bin/activate
8282
ruff check --config ruff.toml hololinked/client
83+
ruff check --config ruff.toml hololinked/serializers
8384
8485
- name: run ty type checker
8586
if: matrix.tool == 'ty'
8687
run: |
8788
source .venv/bin/activate
8889
ty check hololinked/client
90+
ty check hololinked/serializers
8991
9092
scan:
9193
name: security scan (${{ matrix.tool }})

hololinked/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
__version__ = "0.3.12"
1+
"""beginner friendly data acquisition and IoT in python."""
2+
3+
__version__ = "0.4.0"
24

35
from .config import global_config # noqa
46
import hololinked.core # noqa: F401
7+
import hololinked.serializers # noqa: F401

hololinked/client/factory.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
OAuthDirectAccessGrant,
2626
)
2727
from hololinked.constants import ZMQ_TRANSPORTS
28-
from hololinked.core import Thing
29-
from hololinked.serializers import Serializers
28+
from hololinked.core import Serializers, Thing
3029
from hololinked.td.interaction_affordance import (
3130
ActionAffordance,
3231
EventAffordance,

hololinked/client/http/consumed_interactions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
)
2121
from hololinked.client.exceptions import raise_local_exception
2222
from hololinked.constants import Operations
23-
from hololinked.serializers import Serializers
23+
from hololinked.core import Serializers
2424
from hololinked.td.forms import Form
2525
from hololinked.td.interaction_affordance import (
2626
ActionAffordance,

hololinked/client/mqtt/consumed_interactions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from paho.mqtt.client import MQTTMessage
1111

1212
from hololinked.client.abstractions import SSE, ConsumedThingEvent
13-
from hololinked.serializers import BaseSerializer, Serializers # noqa: F401
13+
from hololinked.core import Serializers
14+
from hololinked.core.interfaces import BaseSerializer # noqa: F401
1415
from hololinked.td.forms import Form
1516
from hololinked.td.interaction_affordance import EventAffordance, PropertyAffordance
1617

hololinked/client/zmq/consumed_interactions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
TIMEOUT,
3636
ResponseMessage,
3737
)
38-
from ...serializers.payloads import SerializableData
38+
from ...core.zmq.payloads import SerializableData
3939
from ...td import ActionAffordance, EventAffordance, PropertyAffordance
4040
from ...td.forms import Form
4141
from ..exceptions import ReplyNotArrivedError

hololinked/core/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
"""
2+
Core logic, what is a Property, Action or Event, what is a Thing and how request-reply and pub-sub patterns work.
3+
4+
State machines, meta classes, descriptor registries and the concrete implementation of how an operation is executed
5+
is also included here.
6+
"""
17
# Order of import is reflected in this file to avoid circular imports
8+
29
from .thing import * # noqa
310
from .events import * # noqa
411
from .actions import * # noqa
512
from .property import * # noqa
613
from .state_machine import StateMachine as StateMachine
714
from .meta import ThingMeta as ThingMeta
15+
from .serializer_registry import Serializers as Serializers

hololinked/core/events.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class EventDispatcher:
9494
def __init__(
9595
self,
9696
unique_identifier: str,
97-
publisher: "EventPublisher",
97+
publisher: "EventPublisher", # noqa TODO fix
9898
owner_inst: ParameterizedMetaclass,
9999
descriptor: Event,
100100
) -> None:
@@ -104,12 +104,15 @@ def __init__(
104104
self.publisher = publisher
105105

106106
@property
107-
def publisher(self) -> "EventPublisher":
107+
def publisher(self) -> "EventPublisher": # noqa TODO fix
108108
"""Event publishing PUB socket owning object"""
109109
return self._publisher
110110

111111
@publisher.setter
112-
def publisher(self, value: "EventPublisher") -> None:
112+
def publisher(self, value: "EventPublisher") -> None: # noqa TODO fix
113+
# TODO fix this once the architecture is resolved
114+
from .zmq.brokers import EventPublisher # noqa: E402
115+
113116
if not hasattr(self, "_publisher"):
114117
self._publisher = value
115118
elif not isinstance(value, EventPublisher):
@@ -119,7 +122,7 @@ def publisher(self, value: "EventPublisher") -> None:
119122

120123
def push(self, data: Any) -> None:
121124
"""
122-
publish the event. Multipart payloads are not supported. Supply either a serializable object or a
125+
Publish the event. Multipart payloads are not supported. Supply either a serializable object or a
123126
bytes object for binary data, not both.
124127
125128
Parameters
@@ -148,9 +151,6 @@ def _set_acknowledgement(self, *args, **kwargs) -> None:
148151
self._synchronize_event.set()
149152

150153

151-
from .zmq.brokers import EventPublisher # noqa: E402
152-
153-
154154
__all__ = [
155155
Event.__name__,
156156
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""
2+
Interface classes for dependencies or features that are not part of the main logic.
3+
4+
Follows Hexagonal Architecture.
5+
"""
6+
7+
# TODO once all items have base classes, dont use relative imports.
8+
from .serializer import BaseSerializer as BaseSerializer
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Base class for serializer implementations."""
2+
3+
from typing import Any
4+
5+
6+
class BaseSerializer(object):
7+
"""
8+
Base class for serializer implementations.
9+
10+
All serializers must inherit this class
11+
and overload dumps() and loads() to be usable. Any serializer
12+
that returns bytes when serialized and a python object on deserialization will be accepted.
13+
Serialization and deserialization errors will be passed as invalid message type
14+
from server side and a exception will be raised on the client.
15+
"""
16+
17+
def __init__(self) -> None:
18+
super().__init__()
19+
self.type = None
20+
21+
def loads(self, data) -> Any:
22+
"""Deserialize data."""
23+
raise NotImplementedError("implement loads()/deserialization in subclass")
24+
25+
def dumps(self, data) -> bytes:
26+
"""Serialize data."""
27+
raise NotImplementedError("implement dumps()/serialization in subclass")
28+
29+
def convert_to_bytes(self, data) -> bytes:
30+
"""
31+
Convert data to bytes if it is bytearray or memoryview.
32+
33+
Returns
34+
-------
35+
bytes
36+
37+
Raises
38+
------
39+
TypeError
40+
if data is not bytes, bytearray or memoryview
41+
"""
42+
if isinstance(data, bytes):
43+
return data
44+
if isinstance(data, bytearray):
45+
return bytes(data)
46+
if isinstance(data, memoryview):
47+
return data.tobytes()
48+
raise TypeError(
49+
"serializer convert_to_bytes accepts only bytes, bytearray or memoryview, not type {}".format(type(data))
50+
)
51+
52+
@property
53+
def content_type(self) -> str:
54+
"""Content type of the serializer."""
55+
raise NotImplementedError("serializer must implement a content type")

0 commit comments

Comments
 (0)