Skip to content

Routers

Qualified Router

FastAPI APIrouter with a 'rules' parameter.

Use it to avoid multiple and/or redudant rule declarations in same business area endpoints.

Lorem ipsum

You can also declare aditional rules in a Qualified Router, as it will also get evaluated in addition to the already declared router rules.

Usage example

# qualified_router.py

import missil
from missil.routers import QualifiedRouter
from fastapi import FastAPI

app = FastAPI()

TOKEN_KEY = "Authorization"
SECRET_KEY = "verysecuresecret"

# will expect a token sent in the Authorization header 
bearer = missil.HTTPTokenBearer(TOKEN_KEY, SECRET_KEY, "userPermissions")

finances = missil.make_rule(bearer, "finances")
finances_router = QualifiedRouter(rules=[finances.READ])

@finances_router.get("/finances/read")
async def finances_read_route() -> dict[str, str]:
    """Require read permission on finances."""
    return {"msg": "finances read access check via router rule!"}

@finances_router.get("/finances/write", dependencies=[finances.WRITE])
async def finances_write_route() -> dict[str, str]:
    """Require write permission on finances using an extra rule."""
    return {"msg": "finances write access check via extra qualified router rule!"}

app.include_router(finances_router)

if __name__ == "__main__":
    import uvicorn

    claims = {"userPermissions": {"finances": 1}}
    token = missil.encode_jwt_token(claims, SECRET_KEY, 8)

    print(f"add this token as an Authorization header: {token}")

    uvicorn.run(
        "qualified_router:app",
        port=8666,
        log_level="info",
        reload=True
    )

Grab the provided token above and make an HTTP request:

import httpx

TOKEN = ""
client = httpx.Client()
url = "localhost:8666/finances/write"
headersList = {
 "Accept": "*/*",
 "User-Agent": "Thunder Client (https://www.thunderclient.com)",
 "Authorization": f"{TOKEN}" 
}

data = client.get(url, headers=headersList)
print(data.text)

API Reference

missil.QualifiedRouter

QualifiedRouter(*, prefix='', rules, tags=None, dependencies=None, default_response_class=JSONResponse, responses=None, callbacks=None, routes=None, redirect_slashes=True, default=None, dependency_overrides_provider=None, route_class=APIRoute, on_startup=None, on_shutdown=None, lifespan=None, deprecated=None, include_in_schema=True, generate_unique_id_function=generate_unique_id)

Bases: APIRouter

Fastapi router with rules parameter.

FastAPI APIRouter class, plus an extra rules parameter.

It can be used to avoid multiple redudant rule declarations in same business area endpoints.

Example:

ba = missil.make_rules(bearer, "finances")  # business area
sample_rule_router = missil.QualifiedRouter(rules=[ba["finances"].READ])

All other original parameters are explicit declared to allow autocomplete and intellisense-like code editor capabilities. They are exactly the same as in FastAPI APIrouter class.

PARAMETER DESCRIPTION
rules

Sequence of Missil rule objects.

TYPE: Sequence[Rule]

Source code in missil/routers.py
def __init__(
    self,
    *,
    prefix: str = "",
    rules: Sequence[Rule],
    tags: list[str | Enum] | None = None,
    dependencies: Sequence[FastAPIDependsClass] | None = None,
    default_response_class: type[Response] = JSONResponse,
    responses: dict[int | str, dict[str, Any]] | None = None,
    callbacks: list[BaseRoute] | None = None,
    routes: list[BaseRoute] | None = None,
    redirect_slashes: bool = True,
    default: ASGIApp | None = None,
    dependency_overrides_provider: Any | None = None,
    route_class: type[APIRoute] = APIRoute,
    on_startup: Sequence[Callable[[], Any]] | None = None,
    on_shutdown: Sequence[Callable[[], Any]] | None = None,
    lifespan: Lifespan[Any] | None = None,
    deprecated: bool | None = None,
    include_in_schema: bool = True,
    generate_unique_id_function: Callable[[APIRoute], str] = generate_unique_id,
) -> None:
    """
    FastAPI APIRouter class, plus an extra rules parameter.

    It can be used to avoid multiple redudant rule declarations in same
    business area endpoints.

    Example:

    ```python
    ba = missil.make_rules(bearer, "finances")  # business area
    sample_rule_router = missil.QualifiedRouter(rules=[ba["finances"].READ])
    ```

    All other original parameters are explicit declared to allow autocomplete and
    intellisense-like code editor capabilities. They are exactly the same as in
    FastAPI APIrouter class.

    Parameters
    ----------
    rules : Sequence[Rule]
        Sequence of Missil rule objects.
    """
    super().__init__(
        prefix=prefix,
        tags=tags,
        dependencies=dependencies,
        default_response_class=default_response_class,
        responses=responses,
        callbacks=callbacks,
        routes=routes,
        redirect_slashes=redirect_slashes,
        default=default,
        dependency_overrides_provider=dependency_overrides_provider,
        route_class=route_class,
        on_startup=on_startup,
        on_shutdown=on_shutdown,
        lifespan=lifespan,
        deprecated=deprecated,
        include_in_schema=include_in_schema,
        generate_unique_id_function=generate_unique_id_function,
    )

    self.dependencies += rules