Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ v0.4.3
- Added on_ready callback to RSocketServer. Called when sender/receiver tasks are ready
- Implement ReactiveX (3.0, 4.0) server side handler. Allows to define RequestHandler directly using ReactiveX
- Added sending_done_event argument to request_channel to allow client to wait until sending to server is complete/canceled
- Added find_by_mimetype to CompositeMetadata class. Returns list of relevant items by mimetype
- Breaking Change: Removed RSocketBase class dependency from RequestHandler. It is not longer required as an argument to __init__

v0.4.2
Expand Down
8 changes: 6 additions & 2 deletions rsocket/extensions/composite_metadata.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import List, Type
from typing import List, Type, Union

from rsocket.extensions.authentication_content import AuthenticationContent
from rsocket.extensions.composite_metadata_item import CompositeMetadataItem
from rsocket.extensions.mimetypes import WellKnownMimeTypes
from rsocket.extensions.mimetypes import WellKnownMimeTypes, ensure_encoding_name
from rsocket.extensions.routing import RoutingMetadata
from rsocket.extensions.stream_data_mimetype import StreamDataMimetype
from rsocket.extensions.stream_data_mimetype import StreamDataMimetypes
Expand Down Expand Up @@ -40,6 +40,10 @@ def append(self, item: CompositeMetadataItem) -> 'CompositeMetadata':
self.items.append(item)
return self

def find_by_mimetype(self, mimetype: Union[WellKnownMimeTypes, str, bytes]) -> List[CompositeMetadataItem]:
mimetype_name = ensure_encoding_name(mimetype)
return [item for item in self.items if ensure_encoding_name(item.encoding) == mimetype_name]

def extend(self, *items: CompositeMetadataItem) -> 'CompositeMetadata':
self.items.extend(items)
return self
Expand Down
6 changes: 3 additions & 3 deletions rsocket/extensions/composite_metadata_item.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Union, Optional

from rsocket.extensions.mimetypes import WellKnownMimeTypes
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType, ensure_well_known_encoding_enum_value

_default = object()

Expand All @@ -18,9 +18,9 @@ class CompositeMetadataItem:
)

def __init__(self,
encoding: Union[bytes, WellKnownMimeTypes] = _default,
encoding: Union[bytes, WellKnownMimeTypes, WellKnownMimeType] = _default,
body: Optional[bytes] = _default):
self.encoding = default_or_value(encoding)
self.encoding = ensure_well_known_encoding_enum_value(default_or_value(encoding))
self.content = default_or_value(body)

def parse(self, buffer: bytes):
Expand Down
7 changes: 4 additions & 3 deletions rsocket/extensions/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def composite(*items) -> bytes:
return metadata.serialize()


def metadata_item(data: bytes, encoding: Union[bytes, WellKnownMimeTypes]) -> CompositeMetadataItem:
def metadata_item(data: bytes,
encoding: Union[bytes, WellKnownMimeTypes, WellKnownMimeType]) -> CompositeMetadataItem:
return CompositeMetadataItem(encoding, data)


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


def data_mime_type(metadata_mime_type: Union[bytes, WellKnownMimeType]) -> CompositeMetadataItem:
def data_mime_type(metadata_mime_type: Union[bytes, WellKnownMimeType]) -> StreamDataMimetype:
return StreamDataMimetype(metadata_mime_type)


def data_mime_types(*metadata_mime_types: Union[bytes, WellKnownMimeType]) -> CompositeMetadataItem:
def data_mime_types(*metadata_mime_types: Union[bytes, WellKnownMimeType]) -> StreamDataMimetypes:
return StreamDataMimetypes(list(metadata_mime_types))


Expand Down
19 changes: 19 additions & 0 deletions rsocket/extensions/mimetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class WellKnownType:
__slots__ = (
'name',
'id'
)

def __init__(self, name: bytes, id_: int):
self.name = name
self.id = id_

def __eq__(self, other):
return self.name == other.name and self.id == other.id

def __hash__(self):
return hash((self.id, self.name))


class WellKnownMimeType(WellKnownType):
pass
14 changes: 9 additions & 5 deletions rsocket/extensions/mimetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
from typing import Optional, Union

from rsocket.exceptions import RSocketUnknownMimetype
from rsocket.extensions.mimetype import WellKnownMimeType
from rsocket.frame_helpers import ensure_bytes
from rsocket.helpers import WellKnownType, map_types_by_id, map_types_by_name


class WellKnownMimeType(WellKnownType):
pass
from rsocket.helpers import map_types_by_id, map_types_by_name


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

return ensure_bytes(encoding)


def ensure_well_known_encoding_enum_value(data_encoding):
if isinstance(data_encoding, WellKnownMimeTypes):
data_encoding = data_encoding.value

return data_encoding
9 changes: 1 addition & 8 deletions rsocket/extensions/stream_data_mimetype.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
from typing import Optional, List, Union

from rsocket.extensions.composite_metadata_item import CompositeMetadataItem
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType
from rsocket.extensions.mimetypes import WellKnownMimeTypes, WellKnownMimeType, ensure_well_known_encoding_enum_value
from rsocket.helpers import parse_well_known_encoding, serialize_well_known_encoding


def ensure_well_known_encoding_enum_value(data_encoding):
if isinstance(data_encoding, WellKnownMimeTypes):
data_encoding = data_encoding.value

return data_encoding


class StreamDataMimetype(CompositeMetadataItem):
__slots__ = (
'data_encoding'
Expand Down
18 changes: 1 addition & 17 deletions rsocket/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from reactivestreams.subscriber import Subscriber
from reactivestreams.subscription import DefaultSubscription
from rsocket.exceptions import RSocketTransportError
from rsocket.extensions.mimetype import WellKnownType
from rsocket.frame import Frame
from rsocket.frame_helpers import serialize_128max_value, parse_type
from rsocket.logger import logger
Expand Down Expand Up @@ -43,23 +44,6 @@ def subscribe(self, subscriber: Subscriber):
subscriber.on_subscribe(self)


class WellKnownType:
__slots__ = (
'name',
'id'
)

def __init__(self, name: bytes, id_: int):
self.name = name
self.id = id_

def __eq__(self, other):
return self.name == other.name and self.id == other.id

def __hash__(self):
return hash((self.id, self.name))


def map_types_by_name(types):
return {value.value.name: value.value for value in types}

Expand Down
42 changes: 38 additions & 4 deletions tests/rsocket/test_composite_metadata.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import cast

import pytest

from rsocket.exceptions import RSocketError
from rsocket.extensions.composite_metadata import CompositeMetadata
from rsocket.extensions.helpers import composite, data_mime_type, data_mime_types
from rsocket.extensions.helpers import composite, data_mime_type, data_mime_types, route, authenticate_simple, \
metadata_item
from rsocket.extensions.mimetypes import WellKnownMimeTypes
from rsocket.extensions.routing import RoutingMetadata
from rsocket.extensions.stream_data_mimetype import StreamDataMimetypes, StreamDataMimetype


def test_tag_composite_metadata_too_long():
Expand All @@ -23,7 +27,8 @@ def test_data_mime_type_composite_metadata():
composite_metadata.parse(data)

assert len(composite_metadata.items) == 1
assert composite_metadata.items[0].data_encoding == b'application/json'
metadata_item_1 = cast(StreamDataMimetype, composite_metadata.items[0])
assert metadata_item_1.data_encoding == b'application/json'

assert composite_metadata.serialize() == data

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

assert len(composite_metadata.items) == 1
assert composite_metadata.items[0].data_encodings[0] == b'application/json'
assert composite_metadata.items[0].data_encodings[1] == b'text/xml'
from typing import cast
metadata_item_1 = cast(StreamDataMimetypes, composite_metadata.items[0])

assert metadata_item_1.data_encodings[0] == b'application/json'
assert metadata_item_1.data_encodings[1] == b'text/xml'

assert composite_metadata.serialize() == data


def test_composite_metadata_find_by_mimetype():
data = composite(
data_mime_types(
WellKnownMimeTypes.APPLICATION_JSON,
WellKnownMimeTypes.TEXT_XML
),
route('login'),
authenticate_simple('abcd', '1234'),
metadata_item(b'some_data_1', WellKnownMimeTypes.TEXT_PLAIN),
metadata_item(b'some_data_2', WellKnownMimeTypes.TEXT_PLAIN),
metadata_item(b'{"key":1}', WellKnownMimeTypes.APPLICATION_JSON),
)

composite_metadata = CompositeMetadata()
composite_metadata.parse(data)

plain_text = composite_metadata.find_by_mimetype(WellKnownMimeTypes.TEXT_PLAIN)

assert len(plain_text) == 2
assert plain_text[0].content == b'some_data_1'
assert plain_text[1].content == b'some_data_2'

authentication_items = composite_metadata.find_by_mimetype(WellKnownMimeTypes.MESSAGE_RSOCKET_AUTHENTICATION)
assert authentication_items[0].authentication.password == b'1234'