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
RedirectResponseto send the user somewhere else. - On Failure: Return a
dictcontaining 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}