Skip to content

Commit

Permalink
Merge pull request #7 from betaboon/fix-dont-assume-json-encoder
Browse files Browse the repository at this point in the history
fix: dont make assumptions about json-serialization
  • Loading branch information
betaboon authored Nov 12, 2022
2 parents 093c139 + 24164d1 commit 09ff16e
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 83 deletions.
36 changes: 5 additions & 31 deletions eventstoredb/events.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from __future__ import annotations

import json
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Literal
from typing import Literal
from uuid import UUID, uuid4


Expand All @@ -20,39 +19,16 @@ class ContentType(str, Enum):

@dataclass
class EventData:
# NOTE order matters due to dataclass-inheritence
type: str
content_type: ContentType
id: UUID = field(default_factory=uuid4)
data: bytes | None = None
metadata: bytes | None = None

def _serialized_data(self) -> bytes | None:
return self.data

def _serialized_metadata(self) -> bytes | None:
return self.metadata


@dataclass
class JsonEvent(EventData):
content_type: Literal[ContentType.JSON] = ContentType.JSON
# TODO it would be great not to use Any here
data: Any | None = None
# TODO it would be great not to use Any here
metadata: Any | None = None

def _serialized_data(self) -> bytes | None:
if self.data:
json_data = json.dumps(self.data)
return json_data.encode()
return None

def _serialized_metadata(self) -> bytes | None:
if self.metadata:
json_data = json.dumps(self.metadata)
return json_data.encode()
return None


@dataclass
Expand All @@ -69,20 +45,18 @@ class RecordedEvent:
revision: int
created: int
position: Position
data: bytes | None
metadata: bytes | None


@dataclass
class JsonRecordedEvent(RecordedEvent):
# TODO it would be great not to use Any here
data: Any | None
# TODO it would be great not to use Any here
metadata: Any | None
...


@dataclass
class BinaryRecordedEvent(RecordedEvent):
data: bytes | None
metadata: bytes | None
...


# TODO does this belong to streams/read/types?
Expand Down
28 changes: 8 additions & 20 deletions eventstoredb/persistent_subscriptions/subscribe/grpc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

import json
from typing import Type
from uuid import UUID

import betterproto
Expand Down Expand Up @@ -127,33 +127,21 @@ def convert_read_response_recorded_event(
commit=message.commit_position,
prepare=message.prepare_position,
)
data = message.data
metadata = message.custom_metadata
# TODO reduce duplication
event_class: Type[JsonRecordedEvent] | Type[BinaryRecordedEvent]
if content_type == ContentType.JSON:
data = json.loads(data.decode()) if data else None
metadata = json.loads(metadata.decode()) if metadata else None
return JsonRecordedEvent(
stream_name=stream_name,
id=id,
revision=message.stream_revision,
type=message.metadata["type"],
content_type=content_type,
created=int(message.metadata["created"]),
position=position,
data=data,
metadata=metadata,
)
return BinaryRecordedEvent(
event_class = JsonRecordedEvent
else:
event_class = BinaryRecordedEvent
return event_class(
stream_name=stream_name,
id=id,
revision=message.stream_revision,
type=message.metadata["type"],
content_type=content_type,
created=int(message.metadata["created"]),
position=position,
data=data,
metadata=metadata,
data=message.data if message.data else None,
metadata=message.custom_metadata if message.custom_metadata else None,
)


Expand Down
10 changes: 4 additions & 6 deletions eventstoredb/streams/append/grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ def create_append_request(event_data: EventData) -> AppendReq:
message.id = Uuid(string=str(event_data.id))
message.metadata["type"] = event_data.type
message.metadata["content-type"] = event_data.content_type
data = event_data._serialized_data()
metadata = event_data._serialized_metadata()
if data:
message.data = data
if metadata:
message.custom_metadata = metadata
if event_data.data:
message.data = event_data.data
if event_data.metadata:
message.custom_metadata = event_data.metadata
return AppendReq(proposed_message=message)


Expand Down
28 changes: 8 additions & 20 deletions eventstoredb/streams/read/grpc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

import json
from typing import Type
from uuid import UUID

import betterproto
Expand Down Expand Up @@ -93,31 +93,19 @@ def convert_read_response_recorded_event(
commit=message.commit_position,
prepare=message.prepare_position,
)
data = message.data
metadata = message.custom_metadata
# TODO reduce duplication
event_class: Type[JsonRecordedEvent] | Type[BinaryRecordedEvent]
if content_type == ContentType.JSON:
data = json.loads(data.decode()) if data else None
metadata = json.loads(metadata.decode()) if metadata else None
return JsonRecordedEvent(
stream_name=stream_name,
id=id,
revision=message.stream_revision,
type=message.metadata["type"],
content_type=content_type,
created=int(message.metadata["created"]),
position=position,
data=data,
metadata=metadata,
)
return BinaryRecordedEvent(
event_class = JsonRecordedEvent
else:
event_class = BinaryRecordedEvent
return event_class(
stream_name=stream_name,
id=id,
revision=message.stream_revision,
type=message.metadata["type"],
content_type=content_type,
created=int(message.metadata["created"]),
position=position,
data=data,
metadata=metadata,
data=message.data if message.data else None,
metadata=message.custom_metadata if message.custom_metadata else None,
)
8 changes: 4 additions & 4 deletions tests/streams/test_append.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async def test_append_to_stream_one_json_with_data(
stream_name=stream_name,
events=JsonEvent(
type="TestEvent",
data={"some": "data"},
data=json.dumps({"some": "data"}).encode(),
),
)

Expand All @@ -96,7 +96,7 @@ async def test_append_to_stream_one_json_with_metadata(
stream_name=stream_name,
events=JsonEvent(
type="TestEvent",
metadata={"meta": "data"},
metadata=json.dumps({"meta": "data"}).encode(),
),
)

Expand All @@ -120,8 +120,8 @@ async def test_append_to_stream_one_json_with_data_and_metadata(
stream_name=stream_name,
events=JsonEvent(
type="TestEvent",
data={"some": "data"},
metadata={"meta": "data"},
data=json.dumps({"some": "data"}).encode(),
metadata=json.dumps({"meta": "data"}).encode(),
),
)

Expand Down
5 changes: 3 additions & 2 deletions tests/streams/test_read.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import uuid
from typing import Any

Expand Down Expand Up @@ -41,7 +42,7 @@ async def test_read_stream_json(
) -> None:
await eventstoredb_client.append_to_stream(
stream_name=stream_name,
events=[JsonEvent(type="Test", data={"some": "data"})],
events=[JsonEvent(type="Test", data=json.dumps({"some": "data"}).encode())],
)

it = eventstoredb_client.read_stream(
Expand All @@ -59,7 +60,7 @@ async def test_read_stream_json(
assert event.revision == 0
assert isinstance(event, JsonRecordedEvent)
assert event.data is not None
assert event.data == {"some": "data"}
assert event.data == json.dumps({"some": "data"}).encode()
assert event.metadata is None


Expand Down

0 comments on commit 09ff16e

Please sign in to comment.