Source code for aioli.controller.base

# -*- coding: utf-8 -*-

import re

from starlette.endpoints import WebSocketEndpoint

from aioli.component import Component, ComponentMeta

from .registry import RouteRegistry


def format_path(*parts):
    path = ""

    for part in parts:
        path = f"/{path}/{part}"

    return re.sub(r"/+", "/", path.rstrip("/"))


class HttpControllerMeta(ComponentMeta):
    def __call__(cls, pkg, *args, **kwargs):
        ctrl = super(HttpControllerMeta, cls).__call__(pkg, *args, **kwargs)
        app = pkg.app

        for handler, route in ctrl.stacks:
            handler_addr = hex(id(handler))
            handler_name = f"{ctrl.__class__.__name__}.{route.name}"

            path_full = format_path(app.conf["api_base"], pkg.path, route.path)

            if not hasattr(ctrl, "pkg"):
                raise Exception(f"Superclass of {ctrl} was never created")

            ctrl.log.info(
                f"Registering Route: {path_full} [{route.method}] => "
                f"{route.name} [{handler_addr}]"
            )

            methods = [route.method]

            app.add_route(path_full, handler, methods, handler_name)
            route.path_full = path_full

        return ctrl


[docs]class BaseHttpController(Component, metaclass=HttpControllerMeta): """HTTP API Controller :param pkg: Attach to this package :var pkg: Parent Package :var config: Package configuration :var log: Controller logger """
[docs] async def on_request(self, *args): """Called on request arrival for this Controller"""
@property def stacks(self): for stack in RouteRegistry.stacks.values(): # Yield only if the stack belongs to the Controller being iterated on if stack.handler.__module__ == self.__module__: yield getattr(self, stack.name), stack
class BaseWebSocketController(WebSocketEndpoint, Component, metaclass=ComponentMeta): path = None encoding = "json"