Skip to content

Commit cd679af

Browse files
authored
Merge pull request #76 from rsocket/composite_item_find_by_mimetype
added composite metadata find_by_mimetype + refactoring
2 parents 0c5d941 + 3d48209 commit cd679af

File tree

9 files changed

+82
-42
lines changed

9 files changed

+82
-42
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ v0.4.3
88
- Added on_ready callback to RSocketServer. Called when sender/receiver tasks are ready
99
- Implement ReactiveX (3.0, 4.0) server side handler. Allows to define RequestHandler directly using ReactiveX
1010
- Added sending_done_event argument to request_channel to allow client to wait until sending to server is complete/canceled
11+
- Added find_by_mimetype to CompositeMetadata class. Returns list of relevant items by mimetype
1112
- Breaking Change: Removed RSocketBase class dependency from RequestHandler. It is not longer required as an argument to __init__
1213

1314
v0.4.2

rsocket/extensions/composite_metadata.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from typing import List, Type
1+
from typing import List, Type, Union
22

33
from rsocket.extensions.authentication_content import AuthenticationContent
44
from rsocket.extensions.composite_metadata_item import CompositeMetadataItem
5-
from rsocket.extensions.mimetypes import WellKnownMimeTypes
5+
from rsocket.extensions.mimetypes import WellKnownMimeTypes, ensure_encoding_name
66
from rsocket.extensions.routing import RoutingMetadata
77
from rsocket.extensions.stream_data_mimetype import StreamDataMimetype
88
from rsocket.extensions.stream_data_mimetype import StreamDataMimetypes
@@ -40,6 +40,10 @@ def append(self, item: CompositeMetadataItem) -> 'CompositeMetadata':
4040
self.items.append(item)
4141
return self
4242

43+
def find_by_mimetype(self, mimetype: Union[WellKnownMimeTypes, str, bytes]) -> List[CompositeMetadataItem]:
44+
mimetype_name = ensure_encoding_name(mimetype)
45+
return [item for item in self.items if ensure_encoding_name(item.encoding) == mimetype_name]
46+
4347
def extend(self, *items: CompositeMetadataItem) -> 'CompositeMetadata':
4448
self.items.extend(items)
4549
return self

rsocket/extensions/composite_metadata_item.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Union, Optional
22

3-
from rsocket.extensions.mimetypes import WellKnownMimeTypes
3+
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType, ensure_well_known_encoding_enum_value
44

55
_default = object()
66

@@ -18,9 +18,9 @@ class CompositeMetadataItem:
1818
)
1919

2020
def __init__(self,
21-
encoding: Union[bytes, WellKnownMimeTypes] = _default,
21+
encoding: Union[bytes, WellKnownMimeTypes, WellKnownMimeType] = _default,
2222
body: Optional[bytes] = _default):
23-
self.encoding = default_or_value(encoding)
23+
self.encoding = ensure_well_known_encoding_enum_value(default_or_value(encoding))
2424
self.content = default_or_value(body)
2525

2626
def parse(self, buffer: bytes):

rsocket/extensions/helpers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ def composite(*items) -> bytes:
1414
return metadata.serialize()
1515

1616

17-
def metadata_item(data: bytes, encoding: Union[bytes, WellKnownMimeTypes]) -> CompositeMetadataItem:
17+
def metadata_item(data: bytes,
18+
encoding: Union[bytes, WellKnownMimeTypes, WellKnownMimeType]) -> CompositeMetadataItem:
1819
return CompositeMetadataItem(encoding, data)
1920

2021

@@ -30,11 +31,11 @@ def route(*paths: str) -> CompositeMetadataItem:
3031
return RoutingMetadata(list(paths))
3132

3233

33-
def data_mime_type(metadata_mime_type: Union[bytes, WellKnownMimeType]) -> CompositeMetadataItem:
34+
def data_mime_type(metadata_mime_type: Union[bytes, WellKnownMimeType]) -> StreamDataMimetype:
3435
return StreamDataMimetype(metadata_mime_type)
3536

3637

37-
def data_mime_types(*metadata_mime_types: Union[bytes, WellKnownMimeType]) -> CompositeMetadataItem:
38+
def data_mime_types(*metadata_mime_types: Union[bytes, WellKnownMimeType]) -> StreamDataMimetypes:
3839
return StreamDataMimetypes(list(metadata_mime_types))
3940

4041

rsocket/extensions/mimetype.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class WellKnownType:
2+
__slots__ = (
3+
'name',
4+
'id'
5+
)
6+
7+
def __init__(self, name: bytes, id_: int):
8+
self.name = name
9+
self.id = id_
10+
11+
def __eq__(self, other):
12+
return self.name == other.name and self.id == other.id
13+
14+
def __hash__(self):
15+
return hash((self.id, self.name))
16+
17+
18+
class WellKnownMimeType(WellKnownType):
19+
pass

rsocket/extensions/mimetypes.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22
from typing import Optional, Union
33

44
from rsocket.exceptions import RSocketUnknownMimetype
5+
from rsocket.extensions.mimetype import WellKnownMimeType
56
from rsocket.frame_helpers import ensure_bytes
6-
from rsocket.helpers import WellKnownType, map_types_by_id, map_types_by_name
7-
8-
9-
class WellKnownMimeType(WellKnownType):
10-
pass
7+
from rsocket.helpers import map_types_by_id, map_types_by_name
118

129

1310
@unique
@@ -92,3 +89,10 @@ def ensure_encoding_name(encoding: Union[WellKnownMimeTypes, str, bytes]) -> byt
9289
return encoding.value.name
9390

9491
return ensure_bytes(encoding)
92+
93+
94+
def ensure_well_known_encoding_enum_value(data_encoding):
95+
if isinstance(data_encoding, WellKnownMimeTypes):
96+
data_encoding = data_encoding.value
97+
98+
return data_encoding

rsocket/extensions/stream_data_mimetype.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
from typing import Optional, List, Union
22

33
from rsocket.extensions.composite_metadata_item import CompositeMetadataItem
4-
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType
4+
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType, ensure_well_known_encoding_enum_value
55
from rsocket.helpers import parse_well_known_encoding, serialize_well_known_encoding
66

77

8-
def ensure_well_known_encoding_enum_value(data_encoding):
9-
if isinstance(data_encoding, WellKnownMimeTypes):
10-
data_encoding = data_encoding.value
11-
12-
return data_encoding
13-
14-
158
class StreamDataMimetype(CompositeMetadataItem):
169
__slots__ = (
1710
'data_encoding'

rsocket/helpers.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from reactivestreams.subscriber import Subscriber
1010
from reactivestreams.subscription import DefaultSubscription
1111
from rsocket.exceptions import RSocketTransportError
12+
from rsocket.extensions.mimetype import WellKnownType
1213
from rsocket.frame import Frame
1314
from rsocket.frame_helpers import serialize_128max_value, parse_type
1415
from rsocket.logger import logger
@@ -43,23 +44,6 @@ def subscribe(self, subscriber: Subscriber):
4344
subscriber.on_subscribe(self)
4445

4546

46-
class WellKnownType:
47-
__slots__ = (
48-
'name',
49-
'id'
50-
)
51-
52-
def __init__(self, name: bytes, id_: int):
53-
self.name = name
54-
self.id = id_
55-
56-
def __eq__(self, other):
57-
return self.name == other.name and self.id == other.id
58-
59-
def __hash__(self):
60-
return hash((self.id, self.name))
61-
62-
6347
def map_types_by_name(types):
6448
return {value.value.name: value.value for value in types}
6549

tests/rsocket/test_composite_metadata.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
from typing import cast
2+
13
import pytest
24

35
from rsocket.exceptions import RSocketError
46
from rsocket.extensions.composite_metadata import CompositeMetadata
5-
from rsocket.extensions.helpers import composite, data_mime_type, data_mime_types
7+
from rsocket.extensions.helpers import composite, data_mime_type, data_mime_types, route, authenticate_simple, \
8+
metadata_item
69
from rsocket.extensions.mimetypes import WellKnownMimeTypes
710
from rsocket.extensions.routing import RoutingMetadata
11+
from rsocket.extensions.stream_data_mimetype import StreamDataMimetypes, StreamDataMimetype
812

913

1014
def test_tag_composite_metadata_too_long():
@@ -23,7 +27,8 @@ def test_data_mime_type_composite_metadata():
2327
composite_metadata.parse(data)
2428

2529
assert len(composite_metadata.items) == 1
26-
assert composite_metadata.items[0].data_encoding == b'application/json'
30+
metadata_item_1 = cast(StreamDataMimetype, composite_metadata.items[0])
31+
assert metadata_item_1.data_encoding == b'application/json'
2732

2833
assert composite_metadata.serialize() == data
2934

@@ -38,7 +43,36 @@ def test_data_mime_types_composite_metadata():
3843
composite_metadata.parse(data)
3944

4045
assert len(composite_metadata.items) == 1
41-
assert composite_metadata.items[0].data_encodings[0] == b'application/json'
42-
assert composite_metadata.items[0].data_encodings[1] == b'text/xml'
46+
from typing import cast
47+
metadata_item_1 = cast(StreamDataMimetypes, composite_metadata.items[0])
48+
49+
assert metadata_item_1.data_encodings[0] == b'application/json'
50+
assert metadata_item_1.data_encodings[1] == b'text/xml'
4351

4452
assert composite_metadata.serialize() == data
53+
54+
55+
def test_composite_metadata_find_by_mimetype():
56+
data = composite(
57+
data_mime_types(
58+
WellKnownMimeTypes.APPLICATION_JSON,
59+
WellKnownMimeTypes.TEXT_XML
60+
),
61+
route('login'),
62+
authenticate_simple('abcd', '1234'),
63+
metadata_item(b'some_data_1', WellKnownMimeTypes.TEXT_PLAIN),
64+
metadata_item(b'some_data_2', WellKnownMimeTypes.TEXT_PLAIN),
65+
metadata_item(b'{"key":1}', WellKnownMimeTypes.APPLICATION_JSON),
66+
)
67+
68+
composite_metadata = CompositeMetadata()
69+
composite_metadata.parse(data)
70+
71+
plain_text = composite_metadata.find_by_mimetype(WellKnownMimeTypes.TEXT_PLAIN)
72+
73+
assert len(plain_text) == 2
74+
assert plain_text[0].content == b'some_data_1'
75+
assert plain_text[1].content == b'some_data_2'
76+
77+
authentication_items = composite_metadata.find_by_mimetype(WellKnownMimeTypes.MESSAGE_RSOCKET_AUTHENTICATION)
78+
assert authentication_items[0].authentication.password == b'1234'

0 commit comments

Comments
 (0)