1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-27 13:34:28 +00:00

Some work on the Network Rework

This commit is contained in:
Steffo 2019-10-18 15:32:16 +02:00
parent 35638bb3cd
commit 9859d422f2
6 changed files with 41 additions and 63 deletions

View file

@ -1,7 +1,7 @@
bcrypt>=3.1.7
discord.py>=1.2.2
python-telegram-bot>=11.1.0
royalherald>=5.0b4
royalherald>=5.0b7
pytest>=4.3.1
psycopg2-binary>=2.8
aiohttp>=3.5.4

View file

@ -28,7 +28,7 @@ class GenericBot:
self._Interface = self._interface_factory()
self._Data = self._data_factory()
self.commands = {}
self.network_handlers: typing.Dict[str, typing.Type[NetworkHandler]] = {}
self.network_handlers: typing.Dict[str, typing.Callable[[typing.Any], typing.Awaitable[typing.Dict]]] = {}
for SelectedCommand in self.uninitialized_commands:
interface = self._Interface()
try:
@ -59,26 +59,25 @@ class GenericBot:
bot = self
loop = self.loop
def register_net_handler(ci, message_type: str, network_handler: typing.Callable):
self.network_handlers[message_type] = network_handler
def register_herald_action(ci,
event_name: str,
coroutine: typing.Callable[[typing.Any], typing.Awaitable[typing.Dict]]) -> None:
self.network_handlers[event_name] = coroutine
def unregister_net_handler(ci, message_type: str):
del self.network_handlers[message_type]
def unregister_herald_action(ci, event_name: str):
del self.network_handlers[event_name]
async def net_request(ci, request: rh.Request, destination: str) -> dict:
async def call_herald_action(ci, destination: str, event_name: str, args: typing.Dict) -> typing.Dict:
if self.network is None:
raise Exception("Royalnet is not enabled on this bot")
response_dict: dict = await self.network.request(request.to_dict(), destination)
if "type" not in response_dict:
raise RoyalnetResponseError("Response is missing a type")
elif response_dict["type"] == "ResponseSuccess":
response: typing.Union[rh.ResponseSuccess, rh.ResponseFailure] = rh.ResponseSuccess.from_dict(response_dict)
elif response_dict["type"] == "ResponseError":
response = rh.ResponseFailure.from_dict(response_dict)
raise UnsupportedError("royalherald is not enabled on this bot")
request: rh.Request = rh.Request(handler=event_name, data=args)
response: rh.Response = await self.network.request(destination=destination, request=request)
if isinstance(response, rh.ResponseFailure):
raise CommandError(f"royalherald action code failed: {response}")
elif isinstance(response, rh.ResponseSuccess):
return response.data
else:
raise RoyalnetResponseError("Response type is unknown")
response.raise_on_error()
return response.data
raise TypeError(f"royalherald returned unknown response: {response}")
return GenericInterface
@ -90,43 +89,31 @@ class GenericBot:
if self.uninitialized_network_config is not None:
self.network: rh.Link = rh.Link(self.uninitialized_network_config.master_uri,
self.uninitialized_network_config.master_secret,
self.interface_name, self._network_handler)
self.interface_name,
self._network_handler)
log.debug(f"Running NetworkLink {self.network}")
self.loop.create_task(self.network.run())
async def _network_handler(self, request_dict: dict) -> dict:
"""Handle a single :py:class:`dict` received from the :py:class:`royalherald.Link`.
Returns:
Another :py:class:`dict`, formatted as a :py:class:`royalherald.Response`."""
# Convert the dict to a Request
try:
request: rh.Request = rh.Request.from_dict(request_dict)
except TypeError:
log.warning(f"Invalid request received: {request_dict}")
return rh.ResponseFailure("invalid_request",
f"The Request that you sent was invalid. Check extra_info to see what you sent.",
extra_info={"you_sent": request_dict}).to_dict()
log.debug(f"Received {request} from the NetworkLink")
async def _network_handler(self, request: rh.Request) -> rh.Response:
try:
network_handler = self.network_handlers[request.handler]
except KeyError:
log.warning(f"Missing network_handler for {request.handler}")
return rh.ResponseFailure("no_handler", f"This Link is missing a network handler for {request.handler}.").to_dict()
try:
return rh.ResponseFailure("no_handler", f"This bot is missing a network handler for {request.handler}.")
else:
log.debug(f"Using {network_handler} as handler for {request.handler}")
response: typing.Union[rh.ResponseSuccess, rh.ResponseFailure] = await getattr(network_handler, self.interface_name)(self, request.data)
return response.to_dict()
try:
response_data = await network_handler(**request.data)
return rh.ResponseSuccess(data=response_data)
except Exception as e:
sentry_sdk.capture_exception(e)
log.debug(f"Exception {e} in {network_handler}")
log.error(f"Exception {e} in {network_handler}")
return rh.ResponseFailure("exception_in_handler",
f"An exception was raised in {network_handler} for {request.handler}. Check "
f"extra_info for details.",
f"An exception was raised in {network_handler} for {request.handler}.",
extra_info={
"type": e.__class__.__name__,
"str": str(e)
}).to_dict()
"message": str(e)
})
def _init_database(self):
"""Create an :py:class:`royalnet.database.Alchemy` with the tables required by the packs. Then,

View file

@ -1,5 +1,6 @@
import typing
import asyncio
import royalherald as rh
from .commanderrors import UnsupportedError
if typing.TYPE_CHECKING:
from .command import Command
@ -17,25 +18,19 @@ class CommandInterface:
def __init__(self):
self.command: typing.Optional[Command] = None # Will be bound after the command has been created
def register_net_handler(self, message_type: str, network_handler: typing.Callable):
"""Register a new handler for messages received through Royalnet."""
raise UnsupportedError("'register_net_handler' is not supported on this platform")
def register_herald_action(self,
event_name: str,
coroutine: typing.Callable[[typing.Any], typing.Awaitable[typing.Dict]]):
raise UnsupportedError(f"{self.register_herald_action.__name__} is not supported on this platform")
def unregister_net_handler(self, message_type: str):
"""Remove a Royalnet handler."""
raise UnsupportedError("'unregister_net_handler' is not supported on this platform")
def unregister_herald_action(self, event_name: str):
raise UnsupportedError(f"{self.unregister_herald_action.__name__} is not supported on this platform")
async def net_request(self, message, destination: str) -> dict:
"""Send data through a :py:class:`royalnet.network.NetworkLink` and wait for a
:py:class:`royalnet.network.Reply`.
Parameters:
message: The data to be sent. Must be :py:mod:`pickle`-able.
destination: The destination of the request, either in UUID format or node name."""
raise UnsupportedError("'net_request' is not supported on this platform")
async def call_herald_action(self, destination: str, event_name: str, args: typing.Dict) -> typing.Dict:
raise UnsupportedError(f"{self.call_herald_action.__name__} is not supported on this platform")
def register_keyboard_key(self, key_name: str, callback: typing.Callable):
raise UnsupportedError("'register_keyboard_key' is not supported on this platform")
raise UnsupportedError(f"{self.register_keyboard_key.__name__} is not supported on this platform")
def unregister_keyboard_key(self, key_name: str):
raise UnsupportedError("'unregister_keyboard_key' is not supported on this platform")
raise UnsupportedError(f"{self.unregister_keyboard_key.__name__} is not supported on this platform")

View file

@ -1,4 +0,0 @@
class NetworkHandler:
"""The NetworkHandler functions are called when a specific Message type is received."""
message_type = NotImplemented

View file

@ -16,7 +16,7 @@ setuptools.setup(
packages=setuptools.find_packages(),
install_requires=["python-telegram-bot>=11.1.0",
"discord.py>=1.0.1",
"royalherald>=5.0b4",
"royalherald>=5.0b7",
"psycopg2-binary>=2.8",
"aiohttp>=3.5.4",
"sqlalchemy>=1.3.2",