From b7436f1ca303ef66e99f6e93f24e1ee7c3ff970f Mon Sep 17 00:00:00 2001 From: John Andersen Date: Wed, 8 Nov 2023 11:30:47 +0100 Subject: [PATCH] federation activitypub bovine: Inline mechanical-bull patchset for handler open and close connection events Signed-off-by: John Andersen --- .../federation_activitypub_bovine.py | 87 +++++++++++++++++-- setup.py | 6 +- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/scitt_emulator/federation_activitypub_bovine.py b/scitt_emulator/federation_activitypub_bovine.py index 8073922d..e3a9e5b8 100644 --- a/scitt_emulator/federation_activitypub_bovine.py +++ b/scitt_emulator/federation_activitypub_bovine.py @@ -1,6 +1,7 @@ import os import sys import json +import enum import types import atexit import base64 @@ -154,6 +155,18 @@ async def mechanical_bull_loop(config): yield +# Begin ActivityPub Actor automation handler code +class HandlerAPIVersion(enum.Enum): + # unstable API version used for development between versions + unstable = enum.auto() + v0_2_5 = enum.auto() + + +class HandlerEvent(enum.Enum): + DATA = enum.auto() + OPENED = enum.auto() + CLOSED = enum.auto() + async def handle( client: bovine.BovineClient, data: dict, @@ -322,14 +335,78 @@ async def federate_created_entries( logger.error(traceback.format_exc()) -import asyncio +async def call_handler_compat(handler, *args, **kwargs): + """Helper function to call a handler across versions of the handler calling + convention. + """ + # Inspect handler to determine accepted arguments and for logging purposes + handler_module = inspect.getmodule(handler) + handler_name = getattr( + handler, "__name__", getattr(handler, "__qualname__", repr(handler)) + ) + parameters = inspect.signature(handler).parameters + + inspect_args = { + name: parameter + for name, parameter in parameters.items() + if parameter.default is inspect.Parameter.empty + } + inspect_kwargs = { + name: parameter + for name, parameter in parameters.items() + if parameter.default is not inspect.Parameter.empty + } + + # Determine version of handler API in use. Assume lowest version if not + handler_api_version = HandlerAPIVersion.unstable + handler_api_version_parameter = inspect_kwargs.get("handler_api_version", None) + if "handler_api_version" in kwargs: + handler_api_version = kwargs["handler_api_version"] + elif "handler_event" not in inspect_kwargs: + handler_api_version = HandlerAPIVersion.v0_2_5 + elif ( + handler_api_version_parameter.annotation is HandlerAPIVersion + and handler_api_version_parameter.default is not inspect.Parameter.empty + ): + handler_api_version = handler_api_version_parameter.default + + # Pass version of handler API called with if not set explictly + if "handler_api_version" not in kwargs: + kwargs["handler_api_version"] = handler_api_version + + # Handle adaptations across versions + if ( + handler_api_version == HandlerAPIVersion.v0_2_5 + and args[list(inspect_args.keys()).index("data")] is None + ): + return + + # Remove unknown arguments which would break calls to older handlers + if len(args) != len(inspect_args): + logger.info( + "%s:%s does not support arguments: %s", + handler_module, + handler_name, + json.dumps(list(inspect_args.keys())[len(args) :]), + ) -import bovine -import json + args = args[: len(inspect_args)] -import logging + remove_kwargs = [keyword for keyword in kwargs if keyword not in inspect_kwargs] + + if remove_kwargs: + logger.info( + "%s:%s does not support keyword arguments: %s", + handler_module, + handler_name, + json.dumps(remove_kwargs), + ) + + for keyword in remove_kwargs: + del kwargs[keyword] -from mechanical_bull.handlers import HandlerEvent, call_handler_compat + # Call handler and return result + return await handler(*args, **kwargs) async def handle_connection(client: bovine.BovineClient, handlers: list): diff --git a/setup.py b/setup.py index a1366729..604b6925 100644 --- a/setup.py +++ b/setup.py @@ -29,11 +29,11 @@ "jsonschema", ], "federation-activitypub-bovine": [ - "tomli", - "tomli-w", "aiohttp", "bovine", - "bovine-tool", + "bovine-store", + "bovine-herd", + "bovine-pubsub", "mechanical-bull", ], },