Decorators — Aquilia Documentation
Comprehensive guide and documentation for Decorators in the Aquilia framework. View API reference, examples, and implementation patterns.
Sessions / Decorators Session Decorators Route decorators compile and inject session instances into controller endpoints. The session object exposes .require(), .ensure(), and .optional() methods, while @stateful binds typed states. session.require() Enforces that a valid session exists. If no session is found, raises SessionRequiredFault (HTTP 401). If authenticated=True is passed, it additionally verifies authentication status, throwing an authentication fault if not logged in. from aquilia import Controller, Get from aquilia.sessions import session, Session class DashboardController(Controller): prefix = "/dashboard" @Get("/") @session.require() async def index(self, ctx, session: Session): """Only accessible with an existing session (anonymous or authenticated).""" return ctx.json( ) @Get("/admin") @session.require(authenticated=True) async def admin(self, ctx, session: Session): """Requires session AND authenticated principal. Raises AUTH_REQUIRED fault if not authenticated. """ return ctx.json( ) session.ensure() Ensures a session exists. If one is present in request headers/cookies, it is resolved; otherwise, a fresh anonymous session is initialized. This decorator is guaranteed never to fail. from aquilia import Controller, Get, Post from aquilia.sessions import session, Session class CartController(Controller): prefix = "/cart" @Get("/") @session.ensure() async def view_cart(self, ctx, session: Session): """Always succeeds. Returns empty cart list if session is new.""" return ctx.json( ) @Post("/add") @session.ensure() async def add_to_cart(self, ctx, session: Session): """Reuses existing session, or creates a new one on the fly.""" body = await ctx.request.json() cart = session.get("cart", []) cart.append(body) session["cart"] = cart # Triggers dirty state for save return ctx.json( , status=201) session.optional() Resolves a session if present, but does not construct a new session on failure. The session argument is injected as None if missing. from aquilia import Controller, Get from aquilia.sessions import session, Session class ProductController(Controller): prefix = "/products" @Get("/:id") @session.optional() async def show(self, ctx, id: str, session: Session | None): """Session may be None.""" product = await Product.objects.get(id=id) theme = "light" if session: theme = session.get("theme", "light") # Track recently viewed list viewed = session.get("recently_viewed", []) viewed.append(id) session["recently_viewed"] = viewed[-5:] return ctx.json( ) @stateful A bare decorator that inspects type hints of the parameter named state. It instantiates that typed state class wrapping the session's data dictionary, automatically syncing modifications. from aquilia import Controller, Get, Post from aquilia.sessions import stateful from aquilia.sessions.state import SessionState, Field class CartState(SessionState): items: list = Field(default_factory=list) subtotal: float = Field(default=0.0) class CartController(Controller): prefix = "/cart" @Get("/") @stateful async def view_cart(self, ctx, state: CartState): """CartState is auto-resolved using type hints of 'state'.""" return ctx.json( ) @Post("/add") @stateful async def add_item(self, ctx, state: CartState): body = await ctx.request.json() state.items.append(body) state.subtotal += body.get("price", 0.0) # Auto-committed to session on handler completion return ctx.json( ) Decorator Comparison Decorator Creates Session? Required? Auth Required? On Failure ))} Combining with Auth System Combine session decorators with auth helpers like `@authenticated` from the authentication module or permission-checking guards: from aquilia.auth import authenticated, guard from aquilia.sessions import session class OrderController(Controller): prefix = "/orders" @Get("/") @authenticated # Enforces authentication (auth module) @guard("orders:read") # Enforces permission (auth module) async def list_orders(self, ctx, principal): orders = await Order.objects.filter(user_id=principal.id) return ctx.json([o.to_dict() for o in orders]) @Post("/") @session.require(authenticated=True) # Enforces session & auth @guard("orders:create") # Enforces permission check async def create_order(self, ctx, session): body = await ctx.request.json() order = await Order.create( user_id=session.principal.id, **body, ) return ctx.json(order.to_dict(), status=201) )
Go to Homepage