Workspace Integration — Aquilia Documentation
Comprehensive guide and documentation for Workspace Integration in the Aquilia framework. View API reference, examples, and implementation patterns.
Sessions / Workspace & Manifest Integration Workspace & Manifest Integration Configure session policies globally on the Workspace builder, override parameters locally at the module manifest level, and inject resolved session states into application services. 1. Workspace-Level Configuration Enable and configure sessions globally on the Workspace builder in workspace.py. This constructs the central SessionEngine and binds it to the server's HTTP middleware stack. from datetime import timedelta from aquilia import Workspace from aquilia.sessions import SessionPolicy, PersistencePolicy, ConcurrencyPolicy, TransportPolicy # Configure global workspace policies workspace = ( Workspace("my-app") .sessions( policies=[ SessionPolicy( name="default", ttl=timedelta(days=7), idle_timeout=timedelta(hours=1), absolute_timeout=timedelta(days=30), rotate_on_use=False, rotate_on_privilege_change=True, fingerprint_binding=False, scope="user", persistence=PersistencePolicy( enabled=True, store_name="default", write_through=True, compress=False, ), concurrency=ConcurrencyPolicy( max_sessions_per_principal=5, behavior_on_limit="evict_oldest", ), transport=TransportPolicy( cookie_name="workspace_session", cookie_secure=False, cookie_httponly=True, cookie_samesite="lax", ), ), ], ) .build() ) 2. Manifest-Level Configuration For isolated modules that need specific session parameters (such as shorter timeouts for payment modules or header-based transports for API domains), you can override configurations in the module's manifest.py file using the real SessionConfig dataclass from aquilia.manifest. from datetime import timedelta from aquilia import AppManifest from aquilia.manifest import SessionConfig manifest = AppManifest( name="payment_gateway", version="1.0.0", description="Secure payment operations", controllers=["modules.payment_gateway.controllers:PaymentController"], services=["modules.payment_gateway.services:TransactionService"], # Module-level session config overrides sessions=[ SessionConfig( name="payment_session", enabled=True, ttl=timedelta(minutes=15), # Short TTL for security idle_timeout=timedelta(minutes=5), # Aggressive inactivity timeout # Transport override transport="cookie", cookie_name="pay_sess_id", cookie_secure=True, cookie_httponly=True, cookie_samesite="Strict", # Storage and encryption store="memory", encryption_enabled=True, encryption_key_env="PAYMENT_SESSION_KEY", serializer="json", # Observability hooks log_lifecycle=True, metrics_enabled=True, ) ] ) 3. Constructor Dependency Injection At request time, the session is registered in the request-scoped DI container. Any class with request scope can automatically accept Session inside its constructor: Note Injecting Session is only supported in request-scoped components. Singleton services attempting to resolve sessions will raise dependency resolution errors. Step 1: Service Constructor Injection from aquilia.di import Inject from aquilia.sessions import Session # CheckoutService runs in request scope class CheckoutService: def __init__(self, session: Session): self.session = session async def add_discount_code(self, code: str) -> float: cart = self.session.get("cart", []) if not cart: return 0.0 self.session["discount_code"] = code # Auto-tracked as dirty subtotal = sum(item["price"] for item in cart) return subtotal * 0.9 Step 2: Inject Service into Controller from aquilia import Controller, Post from aquilia.sessions import session from .services import CheckoutService class CheckoutController(Controller): prefix = "/checkout" # Inject request-scoped CheckoutService def __init__(self, checkout_service: CheckoutService): self.checkout_service = checkout_service # Require a session to ensure the container can resolve the dependency @Post("/discount") @session.require() async def apply_discount(self, ctx): body = await ctx.request.json() code = body.get("code") # CheckoutService modifies session data directly new_total = await self.checkout_service.add_discount_code(code) return ctx.json( ) Request Lifecycle Execution Flow The interaction between configurations, manifests, middleware, and DI occurs in a structured flow: , , , , , ].map((item, i) => ( ))} )
Go to Homepage