Skip to content

FastAPI

masks.fastapi adds masks to a FastAPI app. Python apps explains the settings, the handshake, sessions, and privileges that every framework shares.

  1. Install the package with the fastapi extra:

    Terminal window
    pip install "masks-client[fastapi]"
  2. Create Masks with a Config, and install it on the app:

    import os
    from typing import Annotated
    from fastapi import Depends, FastAPI
    from masks.fastapi import Actor, Config, Masks
    auth = Masks(Config(
    issuer=os.environ["MASKS_ISSUER"],
    resource="https://app.example.com",
    name="Catalog",
    secret=os.environ["SESSION_SECRET"],
    ))
    app = FastAPI()
    auth.install(app)
    @app.get("/settings")
    async def settings(actor: Annotated[Actor, Depends(auth.require())]):
    return {"name": actor.name}

install adds the routes, the session middleware, and the handler for refused requests. Each guard is a FastAPI dependency:

  • auth.require(*privileges) sends a signed-out visitor to sign in and back again, then checks each privilege.
  • auth.protect(*privileges) checks an access token.

Both raise ValueError for a privilege that Config.privileges does not name.

A Starlette app without FastAPI still needs the fastapi extra installed. It adds SessionMiddleware(app, masks=auth) and mounts auth.router.routes.

The session is read the first time a request needs it, so a route that never asks for the actor reads nothing from a session store.

masks.fastapi exports Actor, Config, Masks, Refusal, and SessionMiddleware.

install(app) Adds the session middleware, the routes, and the handler for refused requests.
router An APIRouter with the routes, for an app that adds the middleware itself.
actor A dependency that gives the actor, signed in or not.
require(*privileges, tokens=False) A dependency that needs a sign-in holding each privilege. With tokens=True, it checks a token when the request has an Authorization header or no session.
protect(*privileges) A dependency that needs an access token holding each privilege.
await authorize(request, *privileges, tokens=False) require inside a route. Raises Refusal.
await protected(request, *privileges) protect inside a route. Raises Refusal.
await client(request) A masks.AsyncClient with the app’s credentials.
await start_delegation(request, provider, prompt=None, max_age=None) Starts a delegation. Returns the redirect.
await finish_delegation(request) Finishes it. Returns a masks.HeldConnection.
login_url(return_to="", organization="", privilege=()) A link that starts a sign-in.
logout_url() The path a sign-out form posts to.
await registered(request) Whether masks still knows the app.
connected(request) Whether the app holds credentials.
await session(request) The session, a mutable mapping.
await aclose() Closes the HTTP client.