Skip to content

Bigger Applications

Because fastapi-paseto stores configuration on class state shared by all AuthPASETO instances, you only need to call load_config() once before your routes start handling requests.

In a larger FastAPI application, that usually means loading the config in the module that creates the main FastAPI app and then importing routers normally.

An example file structure

Let's say you have a file structure like this:

.
├── multiple_files
│   ├── __init__.py
│   ├── app.py
│   └── routers
│       ├── __init__.py
│       ├── items.py
│       └── users.py

Here is an example of app.py:

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi_paseto import AuthPASETO
from fastapi_paseto.exceptions import AuthPASETOException
from routers import items, users

app = FastAPI()


@AuthPASETO.load_config
def get_config():
    return {"authpaseto_secret_key": "secret"}


@app.exception_handler(AuthPASETOException)
def authpaseto_exception_handler(request: Request, exc: AuthPASETOException):
    return JSONResponse(status_code=exc.status_code, content={"detail": exc.message})


app.include_router(users.router, tags=["users"])
app.include_router(items.router, tags=["items"])

Here is an example of users.py:

from fastapi import APIRouter, Depends, HTTPException
from fastapi_paseto import AuthPASETO
from pydantic import BaseModel


class User(BaseModel):
    username: str
    password: str


router = APIRouter()


@router.post("/login")
def login(user: User, Authorize: AuthPASETO = Depends()):
    if user.username != "test" or user.password != "test":
        raise HTTPException(status_code=401, detail="Bad username or password")

    access_token = Authorize.create_access_token(subject=user.username)
    return {"access_token": access_token}

Here is an example of items.py:

from fastapi import APIRouter, Depends
from fastapi_paseto import AuthPASETO

router = APIRouter()


@router.get("/items")
def items(Authorize: AuthPASETO = Depends()):
    Authorize.paseto_required()

    items = ["item1", "item2", "item3"]

    return {"items": items}