from typing import Type from fastapi import APIRouter from pydantic import BaseModel from ..errors import UnknownEventError from ...util.events import eventbus, events, AnyEvent, AnyEventType from ...util.logging import get_logger logger = get_logger('nacsos.api.route.events') router = APIRouter() logger.debug('Setup nacsos.api.route.events router') class Event(BaseModel): event: AnyEventType payload: AnyEvent @router.post('/emit') async def emit(event: Event) -> None: """ This route can be used to trigger an event on the system. FIXME: This should require some sort of authentication! :param event: event (incl optional payload) to emit :return: void """ logger.info(f'Received external event to be emitted: {event.event}') emit_event_type: Type[AnyEvent] | None = getattr(events, event.event, None) if emit_event_type is None: raise UnknownEventError(f'Event {event.event} not in {AnyEvent}') if not issubclass(emit_event_type, events.BaseEvent): raise UnknownEventError(f'Event {event.event} is not a valid subclass of `BaseEvent`') emit_event = emit_event_type.model_validate(event.payload) logger.debug(f'Going to emit {emit_event} ({emit_event})') await eventbus.emit_async(emit_event.name, emit_event) # noqa PyProtectedMember # TODO user-configurable triggers (e.g. trigger on event or cron-like) # - create schema, model, crud in nacsos-data (probably could just be a JSONB field in `Project` # - create @startup function that sets up all listeners # - list all triggers # - add trigger # - remove trigger # - update trigger