Skip to content

Commit c7216d7

Browse files
committed
add initial support for payload codec
1 parent b6e0ef4 commit c7216d7

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

tests/codec_test.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import base64
2+
from typing import Type
3+
4+
from xconn.client import connect_anonymous
5+
from xconn import codec
6+
7+
8+
class String(str):
9+
pass
10+
11+
12+
class Base64Codec(codec.Codec[String]):
13+
def name(self) -> str:
14+
return "base64"
15+
16+
def encode(self, obj: String) -> str:
17+
return base64.b64encode(obj.encode("utf-8")).decode("utf-8")
18+
19+
def decode(self, data: str, out_type: Type[String]) -> String:
20+
return out_type(base64.b64decode(data.encode("utf-8")).decode())
21+
22+
23+
def test_base64_codec():
24+
encoder = Base64Codec()
25+
encoded = encoder.encode(String("hello"))
26+
assert isinstance(encoded, str)
27+
28+
decoded = encoder.decode(encoded, String)
29+
assert isinstance(decoded, String)
30+
assert decoded == "hello"
31+
32+
33+
def test_something():
34+
# session = connect_anonymous("ws://localhost:8080/ws", "realm1")
35+
# session.set_payload_codec(Base64Codec())
36+
# result = session.call_object("io.xconn.object", String("hello"), String)
37+
# print(result)
38+
# session.leave()
39+
pass

xconn/codec.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Any, Generic, Type, TypeVar
2+
3+
T = TypeVar("T")
4+
5+
6+
class Codec(Generic[T]):
7+
def name(self) -> str:
8+
raise NotImplementedError
9+
10+
def encode(self, obj: Any) -> bytes | str:
11+
"""Serialize a Python object to bytes."""
12+
raise NotImplementedError
13+
14+
def decode(self, data: bytes | str, out_type: Type[T]) -> T:
15+
"""Deserialize bytes into an instance of out_type."""
16+
raise NotImplementedError

xconn/session.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
from concurrent.futures import Future
44
from threading import Thread
5-
from typing import Callable, Any
5+
from typing import Callable, Any, TypeVar, Type
66
from dataclasses import dataclass
77

88
from wampproto import messages, session, uris
99

1010
from xconn import types, exception, uris as xconn_uris
11+
from xconn.codec import Codec
1112
from xconn.exception import ApplicationError
1213
from xconn.helpers import exception_from_error, SessionScopeIDGenerator
1314

15+
TReq = TypeVar("TReq")
16+
TRes = TypeVar("TRes")
17+
1418

1519
@dataclass
1620
class RegisterRequest:
@@ -90,6 +94,8 @@ def __init__(self, base_session: types.BaseSession):
9094

9195
self._disconnect_callback: list[Callable[[], None] | None] = []
9296

97+
self._payload_codec: Codec = None
98+
9399
thread = Thread(target=self._wait, daemon=False)
94100
thread.start()
95101

@@ -192,6 +198,18 @@ def _process_incoming_message(self, msg: messages.Message):
192198
else:
193199
raise ValueError("received unknown message")
194200

201+
def set_payload_codec(self, codec: Codec) -> None:
202+
self._payload_codec = codec
203+
204+
def call_object(self, procedure: str, request: TReq, return_type: Type[TRes] = None) -> TReq | None:
205+
if self._payload_codec is None:
206+
raise ValueError("no payload codec set")
207+
208+
encoded = self._payload_codec.encode(request)
209+
result = self.call(procedure, [encoded])
210+
211+
return self._payload_codec.decode(result.args[0], return_type)
212+
195213
def call(
196214
self,
197215
procedure: str,

0 commit comments

Comments
 (0)