diff --git a/royalherald/__init__.py b/royalherald/__init__.py index 976f9814..1bcf4263 100644 --- a/royalherald/__init__.py +++ b/royalherald/__init__.py @@ -3,7 +3,7 @@ from .errors import HeraldError, ConnectionClosedError, LinkError, InvalidServer from .link import Link from .package import Package from .request import Request -from .response import ResponseSuccess, ResponseFailure +from .response import Response, ResponseSuccess, ResponseFailure from .server import Server @@ -17,6 +17,7 @@ __all__ = [ "Link", "Package", "Request", + "Response", "ResponseSuccess", "ResponseFailure", "Server", diff --git a/royalherald/errors.py b/royalherald/errors.py index b6b32317..268eb85a 100644 --- a/royalherald/errors.py +++ b/royalherald/errors.py @@ -16,7 +16,3 @@ class ConnectionClosedError(LinkError): class InvalidServerResponseError(LinkError): """The :py:class:`Server` sent invalid data to the :py:class:`Link`.""" - - -class ResponseError(LinkError): - """The :py:class:`Response` was an error, and raise_on_error is :py:const:`True`.""" diff --git a/royalherald/link.py b/royalherald/link.py index 463f8cc4..aef61a35 100644 --- a/royalherald/link.py +++ b/royalherald/link.py @@ -2,11 +2,11 @@ import asyncio import websockets import uuid import functools -import math -import numbers import logging as _logging import typing from .package import Package +from .request import Request +from .response import Response, ResponseSuccess, ResponseFailure from .errors import ConnectionClosedError, InvalidServerResponseError @@ -58,7 +58,8 @@ class Link: self.nid: str = str(uuid.uuid4()) self.secret: str = secret self.websocket: typing.Optional[websockets.WebSocketClientProtocol] = None - self.request_handler = request_handler + # Not sure on the type annotation here + self.request_handler: typing.Callable[[Request], typing.Awaitable[Response]] = request_handler self._pending_requests: typing.Dict[str, PendingRequest] = {} if loop is None: self._loop = asyncio.get_event_loop() @@ -127,15 +128,20 @@ class Link: log.debug(f"Sent package: {package}") @requires_identification - async def request(self, message, destination): - package = Package(message, source=self.nid, destination=destination) + async def request(self, destination: str, request: Request) -> Response: + package = Package(request.to_dict(), source=self.nid, destination=destination) request = PendingRequest(loop=self._loop) self._pending_requests[package.source_conv_id] = request await self.send(package) - log.debug(f"Sent request: {message} -> {destination}") + log.debug(f"Sent to {destination}: {request}") await request.event.wait() - response: dict = request.data - log.debug(f"Received response: {request} -> {response}") + if request.data["type"] == "ResponseSuccess": + response: Response = ResponseSuccess.from_dict(request.data) + elif request.data["type"] == "ResponseFailure": + response: Response = ResponseFailure.from_dict(request.data) + else: + raise TypeError("Unknown response type") + log.debug(f"Received from {destination}: {request} -> {response}") return response async def run(self): @@ -157,7 +163,7 @@ class Link: # Package is a request assert isinstance(package, Package) log.debug(f"Received request {package.source_conv_id}: {package}") - response = await self.request_handler(package.data) - response_package: Package = package.reply(response) + response: Response = await self.request_handler(Request.from_dict(package.data)) + response_package: Package = package.reply(response.to_dict()) await self.send(response_package) log.debug(f"Replied to request {response_package.source_conv_id}: {response_package}") diff --git a/royalherald/response.py b/royalherald/response.py index 58074bc3..f2ed5f24 100644 --- a/royalherald/response.py +++ b/royalherald/response.py @@ -25,10 +25,6 @@ class Response: # noinspection PyArgumentList return cls(**d) - def raise_on_error(self): - """Raise an :py:exc:`ResponseError` if the Response is an error, do nothing otherwise.""" - raise NotImplementedError("Please override Response.raise_on_error()") - class ResponseSuccess(Response): """A response to a successful :py:class:`Request`.""" @@ -42,9 +38,6 @@ class ResponseSuccess(Response): def __repr__(self): return f"{self.__class__.__qualname__}(data={self.data})" - def raise_on_error(self): - pass - class ResponseFailure(Response): """A response to a invalid :py:class:`Request`.""" @@ -56,6 +49,3 @@ class ResponseFailure(Response): def __repr__(self): return f"{self.__class__.__qualname__}(name={self.name}, description={self.description}, extra_info={self.extra_info})" - - def raise_on_error(self): - raise ResponseError(self) diff --git a/royalherald/server.py b/royalherald/server.py index 7a5e3ba3..f7572c41 100644 --- a/royalherald/server.py +++ b/royalherald/server.py @@ -103,6 +103,9 @@ class Server: # Is it nothing? if package.destination == "": return [] + # Is it all possible destinations? + if package.destination == "": + return self.identified_clients # Is it a valid nid? try: destination = str(uuid.UUID(package.destination))