mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-24 03:54:20 +00:00
Some work on the Network Rework
This commit is contained in:
parent
35638bb3cd
commit
9859d422f2
6 changed files with 41 additions and 63 deletions
|
@ -1,7 +1,7 @@
|
||||||
bcrypt>=3.1.7
|
bcrypt>=3.1.7
|
||||||
discord.py>=1.2.2
|
discord.py>=1.2.2
|
||||||
python-telegram-bot>=11.1.0
|
python-telegram-bot>=11.1.0
|
||||||
royalherald>=5.0b4
|
royalherald>=5.0b7
|
||||||
pytest>=4.3.1
|
pytest>=4.3.1
|
||||||
psycopg2-binary>=2.8
|
psycopg2-binary>=2.8
|
||||||
aiohttp>=3.5.4
|
aiohttp>=3.5.4
|
||||||
|
|
|
@ -28,7 +28,7 @@ class GenericBot:
|
||||||
self._Interface = self._interface_factory()
|
self._Interface = self._interface_factory()
|
||||||
self._Data = self._data_factory()
|
self._Data = self._data_factory()
|
||||||
self.commands = {}
|
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:
|
for SelectedCommand in self.uninitialized_commands:
|
||||||
interface = self._Interface()
|
interface = self._Interface()
|
||||||
try:
|
try:
|
||||||
|
@ -59,26 +59,25 @@ class GenericBot:
|
||||||
bot = self
|
bot = self
|
||||||
loop = self.loop
|
loop = self.loop
|
||||||
|
|
||||||
def register_net_handler(ci, message_type: str, network_handler: typing.Callable):
|
def register_herald_action(ci,
|
||||||
self.network_handlers[message_type] = network_handler
|
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):
|
def unregister_herald_action(ci, event_name: str):
|
||||||
del self.network_handlers[message_type]
|
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:
|
if self.network is None:
|
||||||
raise Exception("Royalnet is not enabled on this bot")
|
raise UnsupportedError("royalherald is not enabled on this bot")
|
||||||
response_dict: dict = await self.network.request(request.to_dict(), destination)
|
request: rh.Request = rh.Request(handler=event_name, data=args)
|
||||||
if "type" not in response_dict:
|
response: rh.Response = await self.network.request(destination=destination, request=request)
|
||||||
raise RoyalnetResponseError("Response is missing a type")
|
if isinstance(response, rh.ResponseFailure):
|
||||||
elif response_dict["type"] == "ResponseSuccess":
|
raise CommandError(f"royalherald action code failed: {response}")
|
||||||
response: typing.Union[rh.ResponseSuccess, rh.ResponseFailure] = rh.ResponseSuccess.from_dict(response_dict)
|
elif isinstance(response, rh.ResponseSuccess):
|
||||||
elif response_dict["type"] == "ResponseError":
|
|
||||||
response = rh.ResponseFailure.from_dict(response_dict)
|
|
||||||
else:
|
|
||||||
raise RoyalnetResponseError("Response type is unknown")
|
|
||||||
response.raise_on_error()
|
|
||||||
return response.data
|
return response.data
|
||||||
|
else:
|
||||||
|
raise TypeError(f"royalherald returned unknown response: {response}")
|
||||||
|
|
||||||
return GenericInterface
|
return GenericInterface
|
||||||
|
|
||||||
|
@ -90,43 +89,31 @@ class GenericBot:
|
||||||
if self.uninitialized_network_config is not None:
|
if self.uninitialized_network_config is not None:
|
||||||
self.network: rh.Link = rh.Link(self.uninitialized_network_config.master_uri,
|
self.network: rh.Link = rh.Link(self.uninitialized_network_config.master_uri,
|
||||||
self.uninitialized_network_config.master_secret,
|
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}")
|
log.debug(f"Running NetworkLink {self.network}")
|
||||||
self.loop.create_task(self.network.run())
|
self.loop.create_task(self.network.run())
|
||||||
|
|
||||||
async def _network_handler(self, request_dict: dict) -> dict:
|
async def _network_handler(self, request: rh.Request) -> rh.Response:
|
||||||
"""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")
|
|
||||||
try:
|
try:
|
||||||
network_handler = self.network_handlers[request.handler]
|
network_handler = self.network_handlers[request.handler]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log.warning(f"Missing network_handler for {request.handler}")
|
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()
|
return rh.ResponseFailure("no_handler", f"This bot is missing a network handler for {request.handler}.")
|
||||||
try:
|
else:
|
||||||
log.debug(f"Using {network_handler} as handler for {request.handler}")
|
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)
|
try:
|
||||||
return response.to_dict()
|
response_data = await network_handler(**request.data)
|
||||||
|
return rh.ResponseSuccess(data=response_data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
sentry_sdk.capture_exception(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",
|
return rh.ResponseFailure("exception_in_handler",
|
||||||
f"An exception was raised in {network_handler} for {request.handler}. Check "
|
f"An exception was raised in {network_handler} for {request.handler}.",
|
||||||
f"extra_info for details.",
|
|
||||||
extra_info={
|
extra_info={
|
||||||
"type": e.__class__.__name__,
|
"type": e.__class__.__name__,
|
||||||
"str": str(e)
|
"message": str(e)
|
||||||
}).to_dict()
|
})
|
||||||
|
|
||||||
def _init_database(self):
|
def _init_database(self):
|
||||||
"""Create an :py:class:`royalnet.database.Alchemy` with the tables required by the packs. Then,
|
"""Create an :py:class:`royalnet.database.Alchemy` with the tables required by the packs. Then,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import typing
|
import typing
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import royalherald as rh
|
||||||
from .commanderrors import UnsupportedError
|
from .commanderrors import UnsupportedError
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from .command import Command
|
from .command import Command
|
||||||
|
@ -17,25 +18,19 @@ class CommandInterface:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.command: typing.Optional[Command] = None # Will be bound after the command has been created
|
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):
|
def register_herald_action(self,
|
||||||
"""Register a new handler for messages received through Royalnet."""
|
event_name: str,
|
||||||
raise UnsupportedError("'register_net_handler' is not supported on this platform")
|
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):
|
def unregister_herald_action(self, event_name: str):
|
||||||
"""Remove a Royalnet handler."""
|
raise UnsupportedError(f"{self.unregister_herald_action.__name__} is not supported on this platform")
|
||||||
raise UnsupportedError("'unregister_net_handler' is not supported on this platform")
|
|
||||||
|
|
||||||
async def net_request(self, message, destination: str) -> dict:
|
async def call_herald_action(self, destination: str, event_name: str, args: typing.Dict) -> typing.Dict:
|
||||||
"""Send data through a :py:class:`royalnet.network.NetworkLink` and wait for a
|
raise UnsupportedError(f"{self.call_herald_action.__name__} is not supported on this platform")
|
||||||
: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")
|
|
||||||
|
|
||||||
def register_keyboard_key(self, key_name: str, callback: typing.Callable):
|
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):
|
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")
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
class NetworkHandler:
|
|
||||||
"""The NetworkHandler functions are called when a specific Message type is received."""
|
|
||||||
|
|
||||||
message_type = NotImplemented
|
|
2
setup.py
2
setup.py
|
@ -16,7 +16,7 @@ setuptools.setup(
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
install_requires=["python-telegram-bot>=11.1.0",
|
install_requires=["python-telegram-bot>=11.1.0",
|
||||||
"discord.py>=1.0.1",
|
"discord.py>=1.0.1",
|
||||||
"royalherald>=5.0b4",
|
"royalherald>=5.0b7",
|
||||||
"psycopg2-binary>=2.8",
|
"psycopg2-binary>=2.8",
|
||||||
"aiohttp>=3.5.4",
|
"aiohttp>=3.5.4",
|
||||||
"sqlalchemy>=1.3.2",
|
"sqlalchemy>=1.3.2",
|
||||||
|
|
Loading…
Reference in a new issue