Skip to content

Loaders & Actions

Instead of manually registering router.get() and router.post() endpoints, Albedo looks for specific functions inside your page.py files to handle requests.

Data Fetching: loader()

The loader() function handles GET requests. It fetches data for your page and returns a dictionary. Albedo automatically takes this dictionary and passes it directly into the colocated page.html Jinja template.

# app/pages/dashboard/page.py
def loader():
    return {
        "title": "Dashboard",
        "metrics": {"users": 150, "sales": 3200}
    }

Form Handling: action()

The action() function handles POST requests, such as form submissions. It fully supports FastAPI's native Form() injection.

  • On Success: Return a RedirectResponse to send the user somewhere else.
  • On Failure: Return a dict containing the error. Albedo will automatically re-render the current page and pass your error into the template.
# app/pages/settings/page.py
from typing import Annotated
from fastapi import Form
from fastapi.responses import RedirectResponse

def loader():
    return {"error": None}

def action(username: Annotated[str, Form()]):
    if username == "admin":
        # Validation failed: re-renders the page with the error
        return {
            "error": "Username is already taken!",
            "username": username
        }

    # Success: bounce them back home
    return RedirectResponse(url="/", status_code=303)

Database Injection

Because Albedo sits directly on top of FastAPI, you can use standard dependency injection anywhere. If your loader or action requests a parameter named db, Albedo automatically injects your SQLAlchemy Session.

from sqlalchemy.orm import Session
from app.models.user import User

def loader(db: Session):
    users = db.query(User).all()
    return {"users": users}