# Aquilia Framework — Complete Developer Guide & Reference (Aggregated Context)

This file contains consolidated developer guides, architecture patterns, API references, code examples, and configuration options for the Aquilia async Python web framework.

---
## Aquilia Framework
**URL**: `https://tubox.cloud/docs`

import from 'lucide-react' const RequestLifecycle = () => , , , , , , ] return ( ))} ) } const FEATURE_SPINE_DATA = [ , right: }, , right: }, , right: }, , right: }, , right: }, , right: }, , right: }, , right: }, , right: }, , right: } ] function FeatureArchitectureVisualizer( : ) onMouseLeave= `} > • setHoveredId(row.right.id)} onMouseLeave= `} > • ); })} ); } v · " " Aquilia Framework Production-ready async Python web framework Stop writing routing, config, and deployment boilerplate. Focus only on business logic. Quick Start Architecture What is Aquilia? An async-first Python framework built on an auto-discovery architecture. It ships a built-in ORM, production-ready infrastructure generation, and ML deployment — removing the friction of wiring components together manually. Who is it for? Teams building production APIs who want clean architecture, auto-discovery, and built-in deployment tooling — without the wiring boilerplate of microframeworks or the bloat of legacy monoliths. Core Philosophy Aquilia shifts framework architecture from manual configuration boilerplate to declarative autodiscovery. ✕ Legacy Wiring Manual configuration of components, services, and routing topologies. Wiring boilerplate accumulates as the codebase grows. ✓ Auto-Discovery Programmatic registry structures the module and DI graph automatically. Sensible defaults eliminate setup overhead. ✕ Manual Infra Deployment infrastructure, Dockerfiles, and container charts are treated as an afterthought left to separate operations. ✓ Infra Generation First-class generators build production Render, Docker, and Kubernetes configurations natively from the code topology. ✕ Fragile MLOps Machine Learning serving, metrics, and experimental tracking require building a separate, disjointed middleware stack. ✓ Integrated ML Integrated MLOps serving, experimental tracking, and pipeline plugins are supported out of the box by the runtime. ✕ Boilerplate Overhead Writing repetitive boilerplate code for session storage, clearance guards, cache invalidation, and task queue workers. ✓ Unified Modules Unified batteries-included modules cover clearance access levels, multi-layer caching, mail, and worker pools. Feature Architecture Click on any node in the tactical radar engine schema to inspect its subsystem mapping, declarative syntax, and source code files. Architecture at a Glance Aquilia boots using a programmatic entrypoint that loads the workspace, resolves integrations, auto-discovers manifests, and instantiates the ASGI application: app.py Once booted, inbound requests flow through a deterministic pipeline: Minimal Example A complete Aquilia application with a modern manifest-driven structure, typed database integration, pure-Python ORM model, validation contract, service, and controller: workspace.py modules/core/manifest.py modules/core/contracts.py modules/core/controllers.py Response: users = await self.user_service.list_users() return Response.json( ) @POST("/") async def create_user(self, ctx: RequestCtx) -> Response: contract = UserCreateContract(data=await ctx.json()) await contract.is_sealed_async(raise_fault=True) user = await self.user_service.create_user(contract.validated_data) return Response.json(user.to_dict(), status=201)`} language="python" /> modules/core/services.py list[User]: return await User.objects.all() async def create_user(self, data: dict) -> User: return await User.objects.create( name=data["name"], email=data["email"], )`} language="python" /> modules/core/models.py Run it: aq run or python -m aquilia.cli run — starts the development server with auto-reload on port 8000. Subsystem Map Aquilia is organized into cohesive subsystems, each covered in depth by this documentation: Subsystem Package Key Classes ))} Where to Go Next , , , , , , ].map((link, i) => ( ))} )

### Code Examples
```python
from pathlib import Path
from aquilia.runtime import AquiliaRuntime

_WORKSPACE_ROOT = Path(__file__).resolve().parent.parent

# Boots the entire workspace: configures config loader, auto-discovers manifests, and constructs the DI containers
runtime = AquiliaRuntime.from_workspace(
    workspace_root=_WORKSPACE_ROOT,
    mode="prod",
)
app = runtime.app
```

```python
from aquilia import Workspace, Module
from aquilia.integrations import DatabaseIntegration

workspace = (
    Workspace("my-api")
    .module(
        Module("core")
        .route_prefix("/core")
        .auto_discover(True)
    )
    .integrate(
        DatabaseIntegration(url="sqlite:///db.sqlite3")
    )
)
```

```python
from aquilia import AppManifest

manifest = AppManifest(
    name="core",
    version="1.0.0",
    description="Core module",
    controllers=["modules.core.controllers:UsersController"],
    services=["modules.core.services:UserService"],
    models=["modules.core.models:User"],
    base_path="modules.core",
)

__all__ = ["manifest"]
```



---

## Installation
**URL**: `https://tubox.cloud/docs/installation`

Installation Set up Aquilia in your Python environment System Requirements Python Environment Minimum Version 3.10 Recommended 3.12+ Aquilia heavily uses modern asyncio features and type hints introduced in recent Python versions. Operating System macOS / Linux (Fully Supported) Windows (Fully & Natively Supported) Install from PyPI Install Aquilia using uv (recommended): Or with standard pip: Optional Extras Aquilia uses optional dependencies for specialized subsystems. Install only what you need: Extra Installs When to Use ] ))} Development Install (From Source) To contribute to Aquilia or test against the latest changes: Verify Installation After installation, verify that the CLI (aq) is available: The aq doctor command checks your environment for common issues — missing optional dependencies, incompatible Python versions, and misconfigured workspace files. CLI Entry Points The CLI can be accessed via the registered script or direct module invocation: aq Registered CLI command Recommended The standard shortcut installed globally or in your virtual environment to perform workspace bootstrapping, code generation, migrations, and serving. python -m aquilia.cli Module invocation fallback Invokes the CLI directly through the Python interpreter. Use this fallback if the virtual environment binary path is not added to your shell's $PATH. Troubleshooting aq: command not found Ensure your Python scripts directory is in $PATH. For virtual environments, make sure the venv is activated. Alternatively use python -m aquilia.cli. ModuleNotFoundError: No module named 'click' Click is a core dependency. Reinstall with pip install aquilia --force-reinstall. If using a locked environment, ensure click and pyyaml are included. Python version incompatibility Aquilia requires Python 3.10 or newer. Check with python --version. If you have multiple Python versions installed, use python3.10 -m pip install aquilia. Next Steps → Quick Start: Build your first API → CLI Commands: Full command reference → Project Structure: Understand the workspace layout )

### Code Examples
```python
uv add aquilia
```

```python
pip install aquilia
```

```python
# Install with multiple extras
pip install "aquilia[redis,postgres,auth]"

# Install everything
pip install "aquilia[all]"
```



---

## Quick Start
**URL**: `https://tubox.cloud/docs/quickstart`

Quick Start Build a working API in 5 minutes This guide walks you through creating, configuring, and running an Aquilia application from scratch. By the end, you'll have a multi-endpoint REST API with dependency injection, validation contracts, database models, and unit tests. 1 Create a Workspace Use the aq init workspace command to scaffold a new workspace directory containing standard project configuration files: This command generates the following project layout: Workspace Configuration Open workspace.py to see the Fluent Builder configuration structure. The workspace config manages environment settings, module registrations, and third-party integrations: Starter welcome page The workspace starts with a welcome controller defined in starter.py: 2 Add a Module To add a new feature or logical domain to your workspace, run aq add module [NAME]: This scaffolds a new module directory structure under modules/tasks/: Here is the complete, valid, executable example code for each of these files as scaffolded by the CLI generator: modules/tasks/manifest.py modules/tasks/__init__.py modules/tasks/contracts.py modules/tasks/controllers.py ") async def get_task(self, ctx: RequestCtx, id: int): """Get a task by ID.""" item = await self.service.get_by_id(id) if not item: raise TasksNotFoundFault(item_id=id) return Response.json(item) @PUT("/ ") async def update_task(self, ctx: RequestCtx, id: int, data: TaskContract): """Update a task by ID.""" item = await self.service.update(id, data.to_dict()) if not item: raise TasksNotFoundFault(item_id=id) return Response.json(item) @DELETE("/ ") async def delete_task(self, ctx: RequestCtx, id: int): """Delete a task.""" deleted = await self.service.delete(id) if not deleted: raise TasksNotFoundFault(item_id=id) return Response(status=204)`} language="python" /> modules/tasks/services.py List[dict]: return self._storage async def get_by_id(self, item_id: int) -> Optional[dict]: for item in self._storage: if item["id"] == item_id: return item return None async def create(self, data: dict) -> dict: item = self._storage.append(item) self._next_id += 1 return item async def update(self, item_id: int, data: dict) -> Optional[dict]: item = await self.get_by_id(item_id) if item: item.update(data) return item async def delete(self, item_id: int) -> bool: for i, item in enumerate(self._storage): if item["id"] == item_id: self._storage.pop(i) return True return False`} language="python" /> modules/tasks/faults.py modules/tasks/models.py "`} language="python" /> The CLI auto-discovery updates workspace.py to register your new module as a pointer, ensuring your routes and metadata are wireable: 3 Run the Development Server Upon booting, the compiler outputs the route registrations and subsystem configurations: PUT /tasks/ DELETE /tasks/ Serving on http://127.0.0.1:8000 (Press Ctrl+C to stop)`} language="text" /> Open http://127.0.0.1:8000 in your browser to inspect the dev console. 4 Test with cURL 5 Write Tests Use the built-in AquiliaTestCase to run integration and endpoint verification tests against the modules. You do not need to construct a test client manually; use the built-in self.client property along with status assertion methods: Run the tests using the CLI wrapper: Next Steps , , , , , , ].map((link, i) => ( ))} )

### Code Examples
```python
# Create a new workspace
aq init workspace my-api

# Navigate into it
cd my-api
```

```python
my-api/
├── workspace.py          # Root configuration (integrations, server options)
├── starter.py            # Welcome-page controller (shown at / when debug=True)
├── modules/              # Sub-modules (initially empty)
├── tests/                # Test suite
│   ├── conftest.py
│   └── test_smoke.py
├── requirements.txt      # Project dependencies
├── .env.example          # Environment variables template
└── Makefile              # Developer shortcuts
```

```python
# workspace.py
from aquilia import Workspace, Module
from aquilia import AquilaConfig, Secret, Env
from aquilia.integrations import (
    MiddlewareChain,
    DiIntegration,
    RegistryIntegration,
    RoutingIntegration,
    FaultHandlingIntegration,
    PatternsIntegration,
    DatabaseIntegration,
    CacheIntegration,
)

class BaseEnv(AquilaConfig):
    """Shared defaults — every environment inherits these."""
    env = "dev"

    class server(AquilaConfig.Server):
        host = "127.0.0.1"
        port = 8000
        workers = 1
        reload = True

    class di(AquilaConfig.DI):
        scope_enforcement   = "warn"   # "warn" | "raise" | "off"
        parallel_resolution = False    # set True in prod for concurrent deps

workspace = (
    Workspace("my-api")
    .env_config(BaseEnv)
    .starter("starter")
    .middleware(MiddlewareChain.defaults())
    .integrate(DiIntegration(auto_wire=True))
    .integrate(RegistryIntegration())
    .integrate(RoutingIntegration(strict_matching=True))
    .integrate(FaultHandlingIntegration(default_strategy="propagate"))
    .integrate(PatternsIntegration())
    .integrate(DatabaseIntegration(url="sqlite:///db.sqlite3"))
    .integrate(CacheIntegration(backend="memory"))
)

__all__ = ["workspace"]
```



---

## Developer Integration Guide
**URL**: `https://tubox.cloud/docs/developer-guide`

Developer Integration Guide Connecting DI, Controllers, Contracts, Models, Storage, Cache, and Mail This guide outlines how to build a unified application flow in Aquilia. You will learn how to connect Dependency Injection , HTTP Controllers , validation Contracts , ORM Models , Storage , Cache , and Mail in a single cohesive codebase. 1. Dependency Injection & Service Scopes Mark classes as services using the @service decorator. Constructor parameters are automatically autowired by the container using type hints: from aquilia.di import service from aquilia.cache import CacheService from aquilia.storage import StorageBackend # 1. Registered as a singleton across the entire app scope @service(scope="app") class ProductCatalogService: def __init__(self, cache: CacheService, storage: StorageBackend): self.cache = cache self.storage = storage # 2. Registered once per HTTP request scope and disposed on request end @service(scope="request") class UserContext: def __init__(self): self.user = None 2. Contracts: Schema & Input Validation A Contract defines request data validation schemas. Use the @ward decorator to implement custom cross-field constraints: from aquilia.contracts import Contract, Field, ward class UserRegistrationContract(Contract): email: str = Field(max_length=255) password: str = Field(min_length=8) password_confirm: str = Field() username: str = Field(min_length=3, max_length=50) @ward def validate_password_match(self) -> None: if self.password != self.password_confirm: raise ValueError("Passwords do not match") 3. Models: Database & Transactions Database models inherit from the base Model class. Wrap multiple queries inside atomic() async context managers to execute database transactions: from aquilia.models import Model, CharField, AutoField, atomic class User(Model): id = AutoField(primary_key=True) username = CharField(unique=True, max_length=50) email = CharField(unique=True, max_length=255) password_hash = CharField(max_length=255) avatar_url = CharField(null=True, max_length=512) async def create_user_transaction(user_data: dict, password_hash: str) -> User: # Executes queries inside a database transaction block async with atomic(): user = await User.objects.create( username=user_data["username"], email=user_data["email"], password_hash=password_hash ) return user 4. Putting It All Together: The Unified Controller Here is how to orchestrate a complete flow inside an HTTP Controller . The endpoint binds schema contracts, saves files to StorageBackend , writes transaction records, invalidates related CacheService entries, and dispatches custom TemplateMessage emails: from aquilia import Controller, POST from aquilia.controller import RequestCtx from aquilia.http import Response from aquilia.cache import CacheService from aquilia.storage import StorageBackend from aquilia.mail import TemplateMessage from .contracts import UserRegistrationContract from .models import User, create_user_transaction class RegistrationController(Controller): prefix = "/users" # Dependency Injection automatically wires service parameters def __init__(self, cache: CacheService, storage: StorageBackend): self.cache = cache self.storage = storage @POST("/register") async def register(self, ctx: RequestCtx): # 1. Bind and validate request body against Contract schema contract contract = await ctx.bind(UserRegistrationContract) # 2. Process file uploads via Storage avatar_file = ctx.request.files.get("avatar") avatar_url = None if avatar_file: filename = f"avatars/ .png" await self.storage.save(filename, avatar_file.read()) avatar_url = self.storage.url(filename) # 3. Write data inside a database transaction user = await create_user_transaction(contract.to_dict(), "hashed_pw") if avatar_url: user.avatar_url = avatar_url await user.save() # 4. Invalidate related cache tags await self.cache.delete("catalog:count") # 5. Dispatch template confirmation email msg = TemplateMessage( template="welcome.aqt", context= , subject="Welcome, >!", to=[user.email] ) await msg.asend() return Response.json(user.to_dict(), status=201) Quick Start Introduction )

### Code Examples
```python
from aquilia.di import service
from aquilia.cache import CacheService
from aquilia.storage import StorageBackend

# 1. Registered as a singleton across the entire app scope
@service(scope="app")
class ProductCatalogService:
    def __init__(self, cache: CacheService, storage: StorageBackend):
        self.cache = cache
        self.storage = storage

# 2. Registered once per HTTP request scope and disposed on request end
@service(scope="request")
class UserContext:
    def __init__(self):
        self.user = None
```

```python
from aquilia.contracts import Contract, Field, ward

class UserRegistrationContract(Contract):
    email: str = Field(max_length=255)
    password: str = Field(min_length=8)
    password_confirm: str = Field()
    username: str = Field(min_length=3, max_length=50)

    @ward
    def validate_password_match(self) -> None:
        if self.password != self.password_confirm:
            raise ValueError("Passwords do not match")
```

```python
from aquilia.models import Model, CharField, AutoField, atomic

class User(Model):
    id = AutoField(primary_key=True)
    username = CharField(unique=True, max_length=50)
    email = CharField(unique=True, max_length=255)
    password_hash = CharField(max_length=255)
    avatar_url = CharField(null=True, max_length=512)

async def create_user_transaction(user_data: dict, password_hash: str) -> User:
    # Executes queries inside a database transaction block
    async with atomic():
        user = await User.objects.create(
            username=user_data["username"],
            email=user_data["email"],
            password_hash=password_hash
        )
        return user
```



---

## Architecture
**URL**: `https://tubox.cloud/docs/architecture`

Architecture How Aquilia boots, compiles, and serves requests Overview Aquilia follows a manifest → native runtime architecture. Unlike frameworks that discover components at import time, Aquilia separates declaration from request execution through explicit runtime wiring: Boot Pipeline When you call aq run or instantiate AquiliaServer, the following chain executes: Component Graph The following components are initialized during boot and their relationships: env > .env > config files > defaults) ├── FaultEngine # Typed fault handling with domains and severity ├── Aquilary # Manifest registry │ ├── AquilaryRegistry # Validated app metadata indexed by name │ └── FingerprintGenerator # Content-addressed hashing of artifacts ├── RuntimeRegistry # Compiled runtime state │ ├── DI Containers # One Container per app module (scope: "app") │ │ └── Providers # ClassProvider, FactoryProvider, ValueProvider, … │ ├── Compiled Routes # CompiledController → CompiledRoute[] │ └── Model Schemas # ModelMeta metaclass → table definitions ├── MiddlewareStack # Priority-ordered middleware chain │ ├── ExceptionMiddleware # Global error → Response mapping (priority: 1) │ ├── FaultMiddleware # Fault signal interception (priority: 2) │ ├── ServerRequestScopeMiddleware # Request-scoped child DI container (priority: 5) │ ├── RequestIdMiddleware # Generates X-Request-ID header (priority: 10) │ ├── SessionMiddleware # Session load/save per request (priority: 15) │ ├── AquilAuthMiddleware # Unified auth & identity extraction (priority: 15) │ ├── TemplateMiddleware # Template engine rendering context (priority: 25) │ └── Security & Extensions # ProxyFix (3), HTTPSRedirect (4), Version (5), Static (6), SecurityHeaders (7), HSTS (8), CSP (9), CORS (11), Inspector (11), RateLimit (12), ToolbarInjection (12), CSRF (20), I18n (24), Cache (26) ├── ControllerRouter # URL pattern → CompiledRoute mapping ├── ControllerEngine # Route dispatch + pipeline execution ├── ControllerFactory # Controller instantiation with DI ├── ControllerCompiler # Decorator metadata → CompiledRoute ├── ASGIAdapter # ASGI ↔ Aquilia bridge ├── LifecycleCoordinator # Dependency-ordered startup/shutdown └── AquilaSockets # WebSocket runtime (if enabled)`} language="text" /> Request Lifecycle Every incoming ASGI request flows through this pipeline: Middleware Ordering Middleware is ordered by scope (global ))} DI Container Hierarchy Aquilia creates a hierarchy of DI containers that mirror the scoping model: Configuration Layering Configuration is resolved through a layered merge strategy (higher priority wins): Registry Modes The Aquilary registry operates in one of three modes, affecting validation strictness and debug output: Mode Behavior DEV Relaxed validation, debug error pages, auto-reload, verbose logging, hot-reload support PROD Strict validation, JSON error responses, no debug pages, performance optimizations TEST Relaxed validation, test-specific providers, mock-friendly lifecycle, TransactionTestCase support )

### Code Examples
```python
# 1. ConfigLoader resolves the Python-native configuration (AquilaConfig)
config = ConfigLoader()

# 2. Aquilary.from_manifests() validates and indexes all manifest classes
aquilary = Aquilary.from_manifests(
    manifests=[CoreManifest, UsersManifest],
    config=config,
    mode=RegistryMode.PROD,   # DEV, PROD, or TEST
)

# 3. RuntimeRegistry.from_metadata() prepares runtime metadata
#    - Creates DI Container per app (scope: "app")
#    - Registers ClassProvider for each service
#    - Compiles ControllerCompiler routes for each controller
#    - Builds model schemas through ModelMeta and ModelRegistry
runtime = RuntimeRegistry.from_metadata(aquilary, config)

# 4. AquiliaServer wires everything together
server = AquiliaServer(
    manifests=[CoreManifest, UsersManifest],
    config=config,
    mode=RegistryMode.PROD,
)
# Internally:
#   → Creates FaultEngine
#   → Builds Aquilary + RuntimeRegistry
#   → Registers services in DI containers
#   → Sets up MiddlewareStack (12+ layers)
#   → Creates ControllerFactory, ControllerEngine, ControllerCompiler
#   → Creates ControllerRouter
#   → Builds ASGIAdapter
```

```python
AquiliaServer
├── ConfigLoader                 # Layered config (CLI > env > .env > config files > defaults)
├── FaultEngine                  # Typed fault handling with domains and severity
├── Aquilary                     # Manifest registry
│   ├── AquilaryRegistry         # Validated app metadata indexed by name
│   └── FingerprintGenerator     # Content-addressed hashing of artifacts
├── RuntimeRegistry              # Compiled runtime state
│   ├── DI Containers            # One Container per app module (scope: "app")
│   │   └── Providers            # ClassProvider, FactoryProvider, ValueProvider, …
│   ├── Compiled Routes          # CompiledController → CompiledRoute[]
│   └── Model Schemas            # ModelMeta metaclass → table definitions
├── MiddlewareStack              # Priority-ordered middleware chain
│   ├── ExceptionMiddleware      # Global error → Response mapping (priority: 1)
│   ├── FaultMiddleware          # Fault signal interception (priority: 2)
│   ├── ServerRequestScopeMiddleware # Request-scoped child DI container (priority: 5)
│   ├── RequestIdMiddleware      # Generates X-Request-ID header (priority: 10)
│   ├── SessionMiddleware        # Session load/save per request (priority: 15)
│   ├── AquilAuthMiddleware      # Unified auth & identity extraction (priority: 15)
│   ├── TemplateMiddleware       # Template engine rendering context (priority: 25)
│   └── Security & Extensions    # ProxyFix (3), HTTPSRedirect (4), Version (5), Static (6), SecurityHeaders (7), HSTS (8), CSP (9), CORS (11), Inspector (11), RateLimit (12), ToolbarInjection (12), CSRF (20), I18n (24), Cache (26)
├── ControllerRouter             # URL pattern → CompiledRoute mapping
├── ControllerEngine             # Route dispatch + pipeline execution
├── ControllerFactory            # Controller instantiation with DI
├── ControllerCompiler           # Decorator metadata → CompiledRoute
├── ASGIAdapter                  # ASGI ↔ Aquilia bridge
├── LifecycleCoordinator         # Dependency-ordered startup/shutdown
└── AquilaSockets                # WebSocket runtime (if enabled)
```

```python
# 1. ASGI scope arrives at ASGIAdapter.__call__()
#    The adapter distinguishes between HTTP and WebSocket scopes.

# 2. For HTTP: ASGIAdapter wraps the raw ASGI scope into a Request object
request = Request(scope, receive, send)

# 3. RequestCtx is constructed with request, identity, session, container, state
ctx = RequestCtx(
    request=request,
    identity=None,         # Set by AuthMiddleware
    session=None,          # Set by SessionMiddleware
    container=container,   # Per-request DI container (child of app container)
    state={},              # Mutable state dict for middleware data
    request_id=None,       # Set by RequestIdMiddleware
)

# 4. Middleware chain executes (outermost → innermost):
#    Exception → Fault → RequestScope → RequestId → Session/Auth → Template → …
#    Each middleware calls: await next_handler(request, ctx)

# 5. ControllerRouter.match(path, method) → CompiledRoute
#    Pattern matching uses CompiledPattern with «name:type» syntax

# 6. ControllerEngine.handle(compiled_route, ctx)
#    a. ControllerFactory.create(controller_cls) — per-request DI injection
#    b. Execute pipeline nodes (guards → transforms → handler)
#    c. Call controller.on_request(ctx) lifecycle hook
#    d. Call handler method: response = await controller.method(ctx, **params)
#    e. Call controller.on_response(ctx, response) lifecycle hook

# 7. Response flows back through middleware chain (innermost → outermost)
#    Session middleware saves session, Auth middleware may set cookies, etc.

# 8. Response.send(send) serializes to ASGI and sends to client
```



---

## Project Structure
**URL**: `https://tubox.cloud/docs/project-structure`

Project Structure File layout, conventions, and generated artifacts Standard Workspace Layout A workspace created with aq init workspace my-api produces the following structure. Every directory and file has a specific purpose: Key Files Explained workspace.py The root configuration file. Aquilia's ConfigLoader looks for this file first (Python-first config). It must export a workspace variable containing the Workspace configuration object. .env Environment variables with the AQ_ prefix are automatically loaded. Nested keys use double underscores. Higher priority than config files but lower than CLI arguments. Module Conventions Each module directory follows conventions that Module.auto_discover() uses to find components: File Discovery Scans For Registration ))} The .aquilia/ Trace Directory The .aquilia/ directory is automatically generated at boot/runtime and contains diagnostic artifacts, credentials, caches, and logs. It should be added to .gitignore: File Contents ))} Use aq inspect to query trace artifacts from the command line, or use aq trace for interactive exploration. CLI-Generated Files The aq CLI generates various files. Understanding where they go: Command Generates , , , , , , , ].map(( , i) => ( ))} Next Steps → Workspace Builder: All configuration options → Controllers: Writing request handlers → CLI Reference: All commands in detail )

### Code Examples
```python
my-api/
├── workspace.py              # Root configuration (Workspace/Module/Integration/Environment config)
├── starter.py                # Welcome-page controller (StarterController)
├── requirements.txt          # Python dependencies
├── .env.example              # Environment variable template
├── .gitignore                # Gitignore configuration (ignores secrets & trace directories)
│
├── modules/                  # Application modules (empty by default; add using aq add module)
│
├── tests/                    # Top-level test directory
│   ├── conftest.py           # Shared testing fixtures
│   └── test_smoke.py         # Smoke/verification tests
│
└── LICENSE                   # Selected license file (MIT, Apache-2.0, etc.)
```

```python
from aquilia import Workspace, Module
from aquilia import AquilaConfig, Secret, Env
from aquilia.integrations import (
    MiddlewareChain,
    DiIntegration,
    RegistryIntegration,
    RoutingIntegration,
    FaultHandlingIntegration,
    PatternsIntegration,
    DatabaseIntegration,
    CacheIntegration,
    TemplatesIntegration,
    StaticFilesIntegration,
)

# ── Environment Configuration ────────────────────────────────────
class BaseEnv(AquilaConfig):
    """Shared defaults — every environment inherits these."""
    env = "dev"

    class server(AquilaConfig.Server):
        host    = "127.0.0.1"
        port    = 8000
        workers = 1
        reload  = False

    class auth(AquilaConfig.Auth):
        secret_key      = Secret(env="AQ_SECRET_KEY", default="change-me-in-prod")
        password_hasher = AquilaConfig.PasswordHasher(algorithm="argon2id")

class DevEnv(BaseEnv):
    """Development — hot-reload, debug pages, single worker."""
    env = "dev"

    class server(BaseEnv.server):
        debug   = True
        reload  = True
        workers = 1

class ProdEnv(BaseEnv):
    """Production — multi-worker, no reload, no debug."""
    env = "prod"

    class server(BaseEnv.server):
        host               = Env("AQ_HOST", default="0.0.0.0")
        port               = Env("AQ_PORT", default=8000, cast=int)
        workers            = Env("AQ_WORKERS", default=4, cast=int)
        reload             = False
        access_log         = False

    class auth(BaseEnv.auth):
        secret_key = Secret(env="AQ_SECRET_KEY", required=True)

# ── Workspace Structure ──────────────────────────────────────────
workspace = (
    Workspace(
        name="my-api",
        version="1.0.0",
        description="Aquilia workspace",
    )
    # Wire environment config (resolved by AQ_ENV at runtime)
    .env_config(BaseEnv)

    # Starter module for welcome page
    .starter("starter")

    # Middleware chain
    .middleware(MiddlewareChain.defaults())
    .build()
)
```

```python
# .env
AQ_ENV=dev
AQ_SECRET_KEY=some-highly-secure-secret-key-string
AQ_DATABASE__URL=sqlite:///db.sqlite3
```



---

## Admin Panel Setup
**URL**: `https://tubox.cloud/docs/admin-panel`

import from 'lucide-react' Admin Panel Setup aquilia.admin &bull; Enterprise Operational Control Center Aquilia comes with a built-in admin dashboard (AquilAdmin) that provides real-time control, live monitoring, and configuration analysis. This system is compiled ahead-of-time, uses sandboxed Jinja templates, and secures operations with Argon2id hashing and built-in rate-limiting guards. Operational Modules ORM & Migrations Browse and edit model data, run, verify, or rollback database migrations in real time, and inspect queries using the typed SQL planner. System & Docker Monitor CPU, memory, disk usage, python runtime statistics, and interact directly with Docker containers and Kubernetes Pods. Security & Audit Manage superuser and staff roles, inspect secure audit trails, provision custom API keys, and enforce progressive account lockout rules. Automated Setup The quickest way to configure the admin dashboard is by executing the automated CLI setup command. It scans your environment, configures sessions, database pools, and template registries automatically. 1. Imports & Integrations Check The CLI injects the necessary classes ( AdminIntegration , SessionPolicy, etc.) and sets up security modules in workspace.py. 2. Sessions Configuration Enables secure cookie transport protocols, custom timeouts, and absolute token rotations for admin session persistence. 3. Schema Initialization Generates the required database tables automatically for users, groups, permissions, audit trails, and active sessions. 4. Superuser Creation Prompts you interactively to create your initial superuser credentials. Staff accounts can be added later. CLI Command Reference The aq admin CLI toolchain provides diagnostics, security administration, user account management, and operational commands. aq admin setup Automatically configures workspace.py with default dependencies, runs database table checks/migrations, and configures the initial superuser. Flags & Options -y, --non-interactive Bypasses confirmation queries and proceeds with default updates. --database-url TEXT Connection URL override written directly to the database integration builder. aq admin check Runs pre-flight validation on admin dashboard dependencies. Confirms integrations, cookie policies, database migrations, asset directories, and container configurations. Flags & Options --fix Attempts to dynamically uncomment disabled session lines inside workspace.py. --json Outputs test results as structured JSON metadata, suitable for CI pipelines. aq admin createsuperuser Creates a superuser (role: superadmin) inside the database. Superusers possess full administrative rights over modules, custom permissions, settings, and user groups. Flags & Options --username TEXT Operator login username (minimum 2 characters, unique). --email TEXT Operations email address (unique, validated format). --password TEXT Secure credential string. Prompted interactively if omitted. Enforces standard complexity. --first-name TEXT Optional first name metadata. --last-name TEXT Optional last name metadata. aq admin createstaff Creates a staff user (role: staff). Staff operators have access to the dashboard but cannot manage system permissions, view audit logs, or edit other administrator users. Flags & Options --username TEXT Staff operator login username. --email TEXT Staff operations email address. --password TEXT Secure password. Prompted interactively if omitted. --first-name TEXT Optional first name metadata. --last-name TEXT Optional last name metadata. aq admin listusers Queries the aq_admin_users table to list registered accounts. Shows ID, username, email, active status, user role, and join date. Flags & Options --active-only Filters out accounts that have been deactivated. --json Serializes user objects into a raw JSON list. --database-url TEXT Connection string override. aq admin changepassword Securely updates the login password for the specified user after checking standard complexity policies. Flags & Options USERNAME Target account username. --password TEXT New password. Prompted and masked if omitted. --database-url TEXT Connection string override. aq admin status Outputs the dashboard registration state. Inspects models registered via autodiscover(), showing their class representations and list fields. aq admin audit Queries administrative audit records. Returns chronological logs showing execution timestamps, activity types (logins, data modifications), target models, and operator usernames. Flags & Options --limit INTEGER Maximum entries to return (default is 50). --action TEXT Action filter (e.g. login, create, update, delete, settings_change). --user TEXT Username filter. Password Policy Enforcement All user passwords created via CLI or the admin controller are validated against strict strength checks. A password will be rejected unless it satisfies all of the following rules: Casing & Length Must be at least 8 characters and contain both uppercase and lowercase characters. Digits & Special Symbols Must contain at least one numerical digit and at least one special symbol (e.g., !@#$%^&*()). Workspace Configuration To configure the admin integration manually, register the AdminIntegration class in your root workspace.py: Fluent Integrations API The aquilia.integrations.admin package provides builder interfaces to dynamically configure system panels. AdminModules Toggles administrative modules. Supports both standard dataclass overrides and method-based fluent configurations. Fluent Methods .enable_all() Activates absolutely all modules. .disable_all() Deactivates all optional modules. .enable_orm() / .disable_orm() Toggles database entry browsers. .enable_migrations() / .disable_migrations() Toggles visual migration controllers. .enable_monitoring() / .disable_monitoring() Toggles resource monitor pages. .enable_containers() / .disable_containers() Toggles the Docker panel. .enable_pods() / .disable_pods() Toggles the Kubernetes monitoring dashboard. .enable_tasks() / .disable_tasks() Toggles background cron schedulers. .enable_audit() / .disable_audit() Toggles the administrative action timeline. .enable_api_keys() / .disable_api_keys() Toggles developer API key creation. .with_(**overrides: bool) Returns a copy with overridden key states. AdminSecurity Manages brute-force protection, lockout increments, password security thresholds, and security headers. Fluent Methods .strict_password_policy() Restricts passwords to a minimum length of 12 and requires special symbols, numbers, and case mixes. .relaxed_password_policy() Lowers password minimum length requirement to 8 characters and disables symbols complexity tests. .csrf_enabled_set(enabled: bool) Configures session validation tokens. .no_csrf() Disables active Cross-Site Request Forgery tokens. .no_rate_limit() Disables brute force lockout parameters. .no_security_headers() Disables frame embedding block headers. AdminAudit Controls audit log preservation limits and details what categories of actions are archived. Fluent Methods .enable() / .disable() Toggles audit logs collection. .set_max_entries(n: int) Limits the audit log database count (FIFO eviction kicks in when exceeded, minimum value is 100). .log_logins_set(enabled: bool) Toggles archiving user login attempts. .log_views_set(enabled: bool) Toggles logging admin browser panel loads. .log_searches_set(enabled: bool) Toggles archiving query search details. .exclude_actions(*actions: str) Excludes specific actions (e.g. view, search) from being archived. AdminMonitoring Configures system performance metrics collection parameters. Fluent Methods .enable() / .disable() Toggles resource metric charts page. .all_metrics() Includes cpu, memory, disk, network, process, python, system, and health checks. .metrics_set(*names: str) Selects a subset of system metrics to track. .refresh_interval_set(seconds: int) Sets the interval to query system utilization metrics (minimum value is 5 seconds). AdminSidebar Allows show/hide configuration of menu groups inside the admin dashboard side navigation panel. Fluent Methods .show_all() / .hide_all() Toggles visibility for all navigation categories. .show_overview() / .hide_overview() Toggles the main landing page menu. .show_data() / .hide_data() Toggles the ORM and database section. .show_system() / .hide_system() Toggles the performance charts section. .show_infrastructure() / .hide_infrastructure() Toggles Docker and Pods modules. .show_security() / .hide_security() Toggles accounts and permissions items. .show_devtools() / .hide_devtools() Toggles the settings and query analyzer categories. AdminContainers Controls Docker daemon communication parameters and restricts allowed container operations. Fluent Methods .docker_socket(path: str) Sets connection path to local daemon (e.g. /var/run/docker.sock). .read_only() Restricts interaction. Disables starting, stopping, building, pruning, exec shells, or deleting containers. AdminPods Governs Kubernetes operational modes, restricting pod deletions, context updates, and shell execution capabilities. Fluent Methods .all_namespaces() Instructs the client to fetch details across all active Kubernetes namespaces. .read_only() Disables container scaling, deployments, context switches, apply commands, and pod termination. Common Pitfalls ! Dashboard Assets Fail to Load Ensure that StaticFilesIntegration is registered in your workspace.py. Without static files, the browser cannot download CSS and JS bundles. ! CSRF Validation Errors on Login If running locally without HTTPS, make sure cookie_secure=False is set inside your TransportPolicy. Otherwise, cookies will not be sent back to local endpoints. ! Docker or Pods Panels Grayed Out These panels are disabled if docker or kubectl CLI binaries are missing from your system PATH. Ensure Docker is running and Kubeconfig context is set. )

### Code Examples
```python
aq admin setup
```

```python
aq admin setup --database-url="postgresql://user:pass@localhost:5432/db" --non-interactive
```

```python
aq admin check --fix --json
```



---

## Tutorials Overview
**URL**: `https://tubox.cloud/docs/tutorials/overview`

Tutorials Overview Understanding the Aquilia Application Architecture and Scaffolded Project Layout Welcome to the Aquilia step-by-step tutorials! Aquilia is a high-performance, modular, and manifest-driven ASGI web framework built for Python 3.12+. Before we dive into writing code, let's understand the architectural principles, how to scaffold a new application, and what files are created under the hood. Core Architectural Pillars Manifest-First Topology Topologies and component registries are declared explicitly in Python manifests ( manifest.py ). This guarantees zero implicit class scanning or magic imports during start-up. Contract-Based APIs Input and output structures are validated using Contracts . Contracts act as the single source of truth for validation, serialization, database imprinting, and OpenAPI schema generation. Dependency Injection An async-first DI Container resolves class dependencies, managing lifecycle scopes, validating cross-module boundaries, and preventing circular dependencies. Scaffolding Your First Workspace Aquilia projects are organized inside a Workspace. A workspace defines the shared environment settings, database connections, global middleware, and enabled integrations. To initialize a new workspace, use the aq init workspace command: This scaffolds a production-grade directory layout. Let's inspect the files it generates: Key Scaffolded Files Explained Let's view the exact contents of the primary files generated by the CLI, highlighting how they orchestrate the application lifecycle. workspace.py This is the root configuration file loaded by the aq run server. It defines environment profiles (BaseEnv, DevEnv, ProdEnv) and registers core integrations like the database ORM, dependency injection, caching, and templates. Env → environment variables """ from aquilia import Workspace, Module from aquilia import AquilaConfig, Secret, Env from aquilia.integrations import ( MiddlewareChain, DiIntegration, RegistryIntegration, RoutingIntegration, FaultHandlingIntegration, PatternsIntegration, DatabaseIntegration, CacheIntegration, TemplatesIntegration, StaticFilesIntegration, ) # ── Environment Configuration ──────────────────────────────────── # Operational settings (server, auth, DB, mail) as Python classes. # Activate: AQ_ENV=dev (default) | AQ_ENV=prod class BaseEnv(AquilaConfig): """Shared defaults — every environment inherits these.""" env = "dev" class server(AquilaConfig.Server): host = "127.0.0.1" port = 8000 workers = 1 reload = False # ── Timeouts ─────────────────────────────────────────── # timeout_keep_alive = 5 # seconds to keep idle connections open # timeout_worker_healthcheck = 30 # seconds before worker considered unresponsive # timeout_graceful_shutdown = 30 # seconds to wait on shutdown # ── Limits ───────────────────────────────────────────── # backlog = 2048 # TCP connection backlog # limit_concurrency = None # max concurrent connections # limit_max_requests = None # restart worker after N requests # ── Proxy / Headers ─────────────────────────────────── # proxy_headers = True # trust X-Forwarded-* headers # forwarded_allow_ips = "*" # IPs allowed to set proxy headers # root_path = "" # ASGI root_path for reverse proxies # ── WebSocket ───────────────────────────────────────── # ws_max_size = 16_777_216 # max WebSocket message (16 MiB) # ws_ping_interval = 20.0 # ping every N seconds # ws_ping_timeout = 20.0 # close if pong not received # ── TLS / SSL ───────────────────────────────────────── # ssl_certfile = "/etc/certs/cert.pem" # ssl_keyfile = "/etc/certs/key.pem" # ssl_ca_certs = None # ── Protocol Implementation ─────────────────────────── # http = "auto" # "auto" | "h11" | "httptools" # ws = "auto" # "auto" | "wsproto" | "websockets" | "none" # loop = "auto" # "auto" | "asyncio" | "uvloop" class auth(AquilaConfig.Auth): secret_key = Secret(env="AQ_SECRET_KEY", default="change-me-in-prod") password_hasher = AquilaConfig.PasswordHasher(algorithm="argon2id") class DevEnv(BaseEnv): """Development — hot-reload, debug pages, single worker.""" env = "dev" class server(BaseEnv.server): debug = True reload = True workers = 1 class ProdEnv(BaseEnv): """Production — multi-worker, no reload, no debug.""" env = "prod" class server(BaseEnv.server): host = Env("AQ_HOST", default="0.0.0.0") port = Env("AQ_PORT", default=8000, cast=int) workers = Env("AQ_WORKERS", default=4, cast=int) reload = False access_log = False timeout_keep_alive = 30 limit_max_requests = 10_000 # auto-restart workers after 10k requests proxy_headers = True # trust X-Forwarded-* from load balancer class auth(BaseEnv.auth): secret_key = Secret(env="AQ_SECRET_KEY", required=True) # ── Workspace Structure ────────────────────────────────────────── workspace = ( Workspace( name="test-space", version="1.0.0", description="Aquilia workspace", ) # Wire environment config (resolved by AQ_ENV at runtime) .env_config(BaseEnv) # Starter module -- registered here so the server does not need # to hard-code it. Delete this line (and starter.py) once you # add your own modules with a GET "/" route. .starter("starter") # Add modules here with explicit configuration: # .module(Module("auth", version="1.0.0", description="Authentication module").route_prefix("/api/v1/auth").depends_on("core")) # .module(Module("users", version="1.0.0", description="User management").route_prefix("/api/v1/users").depends_on("auth", "core")) # Middleware chain -- controls which middleware runs and in what order. # Presets: defaults() (dev), production(), minimal() # Custom: MiddlewareChain.chain().use("aquilia.middleware.ExceptionMiddleware", priority=1).use(...) .middleware(MiddlewareChain.defaults()) # Integrations - Configure core systems .integrate(DiIntegration(auto_wire=True)) .integrate(RegistryIntegration()) .integrate(RoutingIntegration(strict_matching=True)) .integrate(FaultHandlingIntegration(default_strategy="propagate")) .integrate(PatternsIntegration()) # Database - Configure the ORM backend .integrate(DatabaseIntegration( url="sqlite:///db.sqlite3", # SQLite (dev) # url="postgresql://user:pass@localhost:5432/test-space", # PostgreSQL pool_size=5, echo=False, auto_migrate=False, )) # Cache - In-memory by default, switch to Redis for production .integrate(CacheIntegration( backend="memory", default_ttl=300, max_size=1024, key_prefix="test-space:", )) # Templates - Fluent configuration .integrate( TemplatesIntegration.builder() .source("templates") .scan_modules() .cached("memory") .secure() ) # Static Files - Serve static assets (CSS, JS, images) .integrate(StaticFilesIntegration( directories= , cache_max_age=86400, etag=True, )) # Sessions (uncomment to enable session management) # .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="test-space_session", # cookie_secure=False, # cookie_httponly=True, # cookie_samesite="lax", # ), # ), # ], # ) # Security (uncomment to enable security middleware) # Fine-grained: use Integration.cors(), Integration.csp(), # Integration.rate_limit() with .integrate(). # .security( # cors_enabled=False, # csrf_protection=False, # helmet_enabled=True, # rate_limiting=False, # ) # Telemetry (uncomment to enable observability) # .telemetry( # tracing_enabled=False, # metrics_enabled=True, # logging_enabled=True, # ) # Admin Dashboard (uncomment to enable admin at /admin/) # Requires: aq admin createsuperuser # .integrate(AdminIntegration( # url_prefix="/admin", # site_title="test-space Admin", # auto_discover=True, # )) )`} language="python" filename="workspace.py" highlightLines= /> starter.py The starter script provides a default welcome endpoint when the server starts up. In production or once custom modules are created, the .starter("starter") pointer is removed from workspace.py, and this file is deleted. Scaffolding Modules with aq add module Aquilia's CLI features a complete code-generation engine to scaffold self-contained application modules. Running aq add module <name> prompts you interactively, but you can also configure options directly using command line arguments. Command Arguments and Options , , , , , , , ].map((opt) => ( ))} Scaffolded Module Directory Layout Executing aq add module <name> generates the following files inside your module directory: / ├── __init__.py ├── manifest.py # Module manifest (single source of truth for dependencies and components) ├── controllers.py # Class-based route handler controllers (e.g. GET, POST endpoints) ├── services.py # Dependency injected services containing business logic ├── models.py # Database ORM models mapping to SQL tables ├── contracts.py # Request/response validation contract contracts using Facets └── faults.py # Module-specific structured domain exception faults`} language="text" /> Default manifest.py Content The manifest.py file acts as the registration hub for all components in the module. Here is the exact scaffolded template generated by the CLI: CLI Usage Examples Enabling the Admin Dashboard Aquilia includes a secure, built-in admin dashboard for user and permissions auditing, database records inspection, Docker container monitoring, and server telemetry. Let's look at how to enable it and set up your credentials. 1. Configure integrations in workspace.py The admin panel requires active session management, database connectivity, and static files configuration. By default, basic admin pages are visible, but advanced systems (monitoring, Kubernetes pods, SQL query profiling, task queues) are opt-in. To enable all administrative modules, you can use the fluent .enable_all() method or the class method AdminModules.all_enabled(): Understanding AdminModules Config Options The AdminModules config class lets you selectively enable or disable admin sections: , , , , , ].map((m) => ( ))} 2. Run Pre-flight Dependency Checks Use the CLI's aq admin check command to statically verify that all dependencies are enabled: 3. Database Migrations (Two-Step Flow) Before creating a superuser, the database tables must exist. Important: You must always run the migrations in two separate steps: Step A: Generate Migration Files (aq db makemigrations) This command inspects all ORM models declared in your module manifests, compares them to database schema snapshots, and generates python migration scripts inside each module's migrations/ directory. Step B: Run Migration (aq db migrate) This command reads the generated migration files, applies table mutations to your database, and registers them in the history logs. 4. Create an Admin Superuser Once migrations are completed, create a superuser using the CLI: Once created, run aq run, navigate to http://127.0.0.1:8000/admin, and log in to explore the dashboard. Running and Verifying the Workspace To spin up the local development server with hot-reloading active, run the following CLI command: The server will start at http://127.0.0.1:8000. Open your browser and navigate to this URL to view the default welcome page. Integrity Validation: You can run aq validate at any time to statically verify module manifests, route configurations, and DI provider chains. Begin Your Journey Now that we understand how a workspace is bootstrapped and what its core structure represents, let's build a real-world application! Click the link below to follow our complete step-by-step tutorial on building a CRUD-based Todo API with database storage. → Build a Todo Application (End-to-End Tutorial) )

### Code Examples
```python
# Create a new workspace named "my_server"
aq init workspace my_server

# Navigate into the generated directory
cd my_server
```

```python
my_server/
├── workspace.py          # Root configuration (integrations, database, environments)
├── starter.py            # Welcome-page controller (runs only when debug=True)
├── modules/              # Sub-modules folder (where your business code lives)
├── tests/                # Test suite with pytest configurations
│   ├── conftest.py       # Shared test fixtures (e.g. TestClient, TestServer)
│   └── test_smoke.py     # Smoke test validating server start-up
├── requirements.txt      # Python dependencies list
├── .env.example          # Environment variables template file
├── .gitignore            # Ignores local databases and the runtime directory
└── Makefile              # Quick developer shortcuts (e.g., make run, make test)
```

```python
"""
Aquilia Workspace Configuration - Production Grade
Generated by: aq init workspace test-space

Single-file workspace configuration.
Everything — structure, modules, integrations, and operational
settings (server, auth, DB) — lives in this one file.

- Type-safe with full IDE support
- Version-controlled and shared across team
- Observable via introspection
- Environment layering via AquilaConfig subclasses

Override order: BaseEnv → <AQ_ENV>Env → environment variables
"""

from aquilia import Workspace, Module
from aquilia import AquilaConfig, Secret, Env
from aquilia.integrations import (
    MiddlewareChain,
    DiIntegration,
    RegistryIntegration,
    RoutingIntegration,
    FaultHandlingIntegration,
    PatternsIntegration,
    DatabaseIntegration,
    CacheIntegration,
    TemplatesIntegration,
    StaticFilesIntegration,
)


# ── Environment Configuration ────────────────────────────────────
# Operational settings (server, auth, DB, mail) as Python classes.
# Activate: AQ_ENV=dev (default) | AQ_ENV=prod

class BaseEnv(AquilaConfig):
    """Shared defaults — every environment inherits these."""
    env = "dev"

    class server(AquilaConfig.Server):
        host    = "127.0.0.1"
        port    = 8000
        workers = 1
        reload  = False

        # ── Timeouts ───────────────────────────────────────────
        # timeout_keep_alive = 5        # seconds to keep idle connections open
        # timeout_worker_healthcheck = 30  # seconds before worker considered unresponsive
        # timeout_graceful_shutdown = 30 # seconds to wait on shutdown

        # ── Limits ─────────────────────────────────────────────
        # backlog            = 2048      # TCP connection backlog
        # limit_concurrency  = None      # max concurrent connections
        # limit_max_requests = None      # restart worker after N requests

        # ── Proxy / Headers ───────────────────────────────────
        # proxy_headers      = True      # trust X-Forwarded-* headers
        # forwarded_allow_ips = "*"      # IPs allowed to set proxy headers
        # root_path          = ""        # ASGI root_path for reverse proxies

        # ── WebSocket ─────────────────────────────────────────
        # ws_max_size        = 16_777_216  # max WebSocket message (16 MiB)
        # ws_ping_interval   = 20.0        # ping every N seconds
        # ws_ping_timeout    = 20.0        # close if pong not received

        # ── TLS / SSL ─────────────────────────────────────────
        # ssl_certfile       = "/etc/certs/cert.pem"
        # ssl_keyfile        = "/etc/certs/key.pem"
        # ssl_ca_certs       = None

        # ── Protocol Implementation ───────────────────────────
        # http = "auto"        # "auto" | "h11" | "httptools"
        # ws   = "auto"        # "auto" | "wsproto" | "websockets" | "none"
        # loop = "auto"        # "auto" | "asyncio" | "uvloop"

    class auth(AquilaConfig.Auth):
        secret_key      = Secret(env="AQ_SECRET_KEY", default="change-me-in-prod")
        password_hasher = AquilaConfig.PasswordHasher(algorithm="argon2id")


class DevEnv(BaseEnv):
    """Development — hot-reload, debug pages, single worker."""
    env = "dev"

    class server(BaseEnv.server):
        debug   = True
        reload  = True
        workers = 1


class ProdEnv(BaseEnv):
    """Production — multi-worker, no reload, no debug."""
    env = "prod"

    class server(BaseEnv.server):
        host               = Env("AQ_HOST", default="0.0.0.0")
        port               = Env("AQ_PORT", default=8000, cast=int)
        workers            = Env("AQ_WORKERS", default=4, cast=int)
        reload             = False
        access_log         = False
        timeout_keep_alive = 30
        limit_max_requests = 10_000   # auto-restart workers after 10k requests
        proxy_headers      = True     # trust X-Forwarded-* from load balancer

    class auth(BaseEnv.auth):
        secret_key = Secret(env="AQ_SECRET_KEY", required=True)


# ── Workspace Structure ──────────────────────────────────────────

workspace = (
    Workspace(
        name="test-space",
        version="1.0.0",
        description="Aquilia workspace",
    )
    # Wire environment config (resolved by AQ_ENV at runtime)
    .env_config(BaseEnv)

    # Starter module -- registered here so the server does not need
    # to hard-code it. Delete this line (and starter.py) once you
    # add your own modules with a GET "/" route.
    .starter("starter")

    # Add modules here with explicit configuration:
    # .module(Module("auth", version="1.0.0", description="Authentication module").route_prefix("/api/v1/auth").depends_on("core"))
    # .module(Module("users", version="1.0.0", description="User management").route_prefix("/api/v1/users").depends_on("auth", "core"))

    # Middleware chain -- controls which middleware runs and in what order.
    # Presets: defaults() (dev), production(), minimal()
    # Custom: MiddlewareChain.chain().use("aquilia.middleware.ExceptionMiddleware", priority=1).use(...)
    .middleware(MiddlewareChain.defaults())

    # Integrations - Configure core systems
    .integrate(DiIntegration(auto_wire=True))
    .integrate(RegistryIntegration())
    .integrate(RoutingIntegration(strict_matching=True))
    .integrate(FaultHandlingIntegration(default_strategy="propagate"))
    .integrate(PatternsIntegration())

    # Database - Configure the ORM backend
    .integrate(DatabaseIntegration(
        url="sqlite:///db.sqlite3",       # SQLite (dev)
        # url="postgresql://user:pass@localhost:5432/test-space",  # PostgreSQL
        pool_size=5,
        echo=False,
        auto_migrate=False,
    ))

    # Cache - In-memory by default, switch to Redis for production
    .integrate(CacheIntegration(
        backend="memory",
        default_ttl=300,
        max_size=1024,
        key_prefix="test-space:",
    ))

    # Templates - Fluent configuration
    .integrate(
        TemplatesIntegration.builder()
        .source("templates")
        .scan_modules()
        .cached("memory")
        .secure()
    )

    # Static Files - Serve static assets (CSS, JS, images)
    .integrate(StaticFilesIntegration(
        directories={"/static": "static"},
        cache_max_age=86400,
        etag=True,
    ))

    # Sessions (uncomment to enable session management)
    # .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="test-space_session",
    #                 cookie_secure=False,
    #                 cookie_httponly=True,
    #                 cookie_samesite="lax",
    #             ),
    #         ),
    #     ],
    # )

    # Security (uncomment to enable security middleware)
    # Fine-grained: use Integration.cors(), Integration.csp(),
    # Integration.rate_limit() with .integrate().
    # .security(
    #     cors_enabled=False,
    #     csrf_protection=False,
    #     helmet_enabled=True,
    #     rate_limiting=False,
    # )

    # Telemetry (uncomment to enable observability)
    # .telemetry(
    #     tracing_enabled=False,
    #     metrics_enabled=True,
    #     logging_enabled=True,
    # )

    # Admin Dashboard (uncomment to enable admin at /admin/)
    # Requires: aq admin createsuperuser
    # .integrate(AdminIntegration(
    #     url_prefix="/admin",
    #     site_title="test-space Admin",
    #     auto_discover=True,
    # ))
)
```



---

## Todo Application
**URL**: `https://tubox.cloud/docs/tutorials/todo-app`

Todo Application End-to-End Beginner-Level Tutorial with Code Examples In this tutorial, you will build a complete, database-backed REST API for a Todo application. You'll learn how to define database models using the Aquilia ORM, create request/response contracts using validation contracts, write business logic inside dependency-injected services, handle client errors using custom faults, and test your work using the built-in test client. ) })} , , , , , , ].map((item) => ( ))} )} language="python" filename="models.py" highlightLines= /> ORM Concept Explanations: • Model: The base class representing an ORM model. Metaclasses scan this subclass, build column registries, and attach a default objects Manager . • AutoField: Creates an autoincrementing integer primary key column. • BooleanField: A boolean field in SQL. Note that the contract validation counterpart is named BoolFacet , which handles type casting from JSON payloads. • class Meta: Metaclass metadata containing table settings, ordering rules (here we sort records in descending order of creation time), indexes, or custom database constraints. )} language="python" filename="services.py" highlightLines= /> DI and Query Concepts: • @service(scope="app"): Registers this service in the dependency injection container. "app" scope is initialized once and cached across requests. • TodoItem.objects: The QuerySet manager. We invoke all() to load all items, get(id=...) for single items, and create(**kwargs) to insert a new row in one command. • save(): An instance method on the model that compiles changed columns and executes an UPDATE SQL statement in the database. )} language="python" filename="controllers.py" highlightLines= /> Controller Route Concepts: • HTTP Verb Decorators: @GET , @POST , etc. bind route patterns to asynchronous handler methods. • request_contract: Enables automatic parsing of request bodies, casting inputs, and raising a SealFault if validation fails. The verified parameters are accessible via contract.validated_data. • response_contract: Filters and serializes model return values. We specify projections, e.g., TodoContract["summary"], to select which columns to output. • Path Parameters: Binds variables from URL paths (e.g. <id:int>) directly as type-coerced arguments in handler signatures. )} language="python" filename="test_todos.py" highlightLines= /> Running the Test Suite: Execute the tests using the aq test command: )} Previous Step Next Step )

### Code Examples
```python
# Generate the module structure inside modules/todos/
aq add module todos
```

```python
# modules/todos/models.py
from aquilia.models import Model
from aquilia.models.fields import (
    AutoField,
    CharField,
    BooleanField,
    DateTimeField,
)


class TodoItem(Model):
    """
    TodoItem database model.
    Maps to the "todos" database table.
    """
    table = "todos"

    id = AutoField(primary_key=True)
    title = CharField(max_length=255)
    completed = BooleanField(default=False)
    created_at = DateTimeField(auto_now_add=True)
    updated_at = DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __repr__(self):
        return f"<TodoItem id={self.id} title={self.title!r} completed={self.completed}>"
```

```python
# modules/todos/contracts.py (Explicit Facet Style)
from aquilia import Contract
from aquilia.contracts import (
    IntFacet,
    TextFacet,
    BoolFacet,
    DateTimeFacet,
)
from .models import TodoItem


class TodoContract(Contract):
    """
    Contract using explicit Facet descriptors.
    """
    id = IntFacet(read_only=True)
    title = TextFacet(max_length=255, required=True, min_length=1)
    completed = BoolFacet(required=False, default=False)
    created_at = DateTimeFacet(read_only=True)

    class Spec:
        model = TodoItem
        extra_fields = "reject"  # Fail if client sends unregistered fields
        projections = {
            "summary": ["id", "title", "completed"],
            "detail": "__all__"
        }
```



---

## Authentication Application
**URL**: `https://tubox.cloud/docs/tutorials/auth-app`

import from 'lucide-react' Tutorials / End-to-End Auth App Authentication Application Learn how to build a complete, production-grade Authentication and Session flow in Aquilia. We will implement user registration, Argon2id password hashing, session lifecycle management, login/logout endpoints, and a guarded profile route. ) })} shift composition operator) to clean inputs: Option A: Explicit Facet Descriptors Uses explicit Facet class descriptors: Option B: Type-Annotated Fields with Wards (Modern Hashing Way) Modern style using type annotations, validation pipelines, and an async @ward method to automatically hash passwords inside the contract itself: > strip >> lower] SlugType = Annotated[str, Facet.text() >> strip >> lower >> slugify] class RegisterContract(Contract): username: SlugType = Field(min_length=3) email: EmailType = Field() password: str = Field(min_length=8) class Spec: model = User fields = ["username", "email"] # Writable fields for imprinting extra_fields = "reject" @ward(mode="async") async def validate_and_hash_password(self, data: dict): password = data.get("password") if not password: self.reject("password", "Password is required") return data # Enforce password strength policy policy = PasswordPolicy(min_length=8) is_valid, errors = await policy.validate_async(password=password) if not is_valid: self.reject("password", errors) # Hash and inject the password_hash directly into validation data dictionary hasher = PasswordHasher() password_hash = await hasher.hash_async(password=password) self.data["password_hash"] = password_hash return data `} language="python" /> Inbound & Outbound Contracts: > strip >> lower] SlugType = Annotated[str, Facet.text() >> strip >> lower >> slugify] class LoginContract(Contract): """ Schema for validating sign-in requests. """ username: str = Field(min_length=3) password: str = Field(min_length=1) class Spec: extra_fields = "reject" class UserResponseContract(Contract): """ Schema for serializing outbound user statistics (masking secrets). """ id: int = Field(read_only=True) username: str = Field(read_only=True) email: str = Field(read_only=True) created_at: datetime = Field(read_only=True) class Spec: model = User fields = ["id", "username", "email", "created_at"] class LoginResponseContract(Contract): """ Outbound response contract after a successful sign-in. """ access_token: str = Field() refresh_token: str = Field() message: str = Field() user: UserResponseContract = Field() # Nested schema `} language="python" filename="contracts.py" highlightLines= /> Understanding Spec Configurations & Methods: • model: Links the contract schema to a database model class. • fields: Filters which model fields should be parsed or serialized. Set to "__all__" to include all fields. • exclude: Excludes specified fields (e.g. secret hash keys) from serialization outputs. • read_only_fields / write_only_fields: Sets unidirectional permissions on properties. • is_sealed(): Evaluates if a contract validation is run successfully. • imprint(): Resolves and saves validated data directly to the database model. )} already exists.") # Hash password and save manually hashed_pass = self.hasher.hash(user_data.password) user = User( username=user_data.username, email=user_data.email, password_hash=hashed_pass, ) await user.save() return user `} language="python" /> Way 2: Automatic DB Imprinting with Contract @ward (Modern Way) Since password validation and hashing occurred automatically in the contract's async @ward , the service doesn't need to manually hash anything. It simply calls imprint() directly: User: """Modern way -- validators and hashes are encapsulated inside the contract.""" existing_user = await User.query().filter(email=user_data.email).first() if existing_user: raise AuthValidationFault(f"A user with this email already exists.") # The contract automatically validated and hashed the password into 'password_hash'. # imprint() creates and saves the User model instance in one step. user = await user_data.imprint() return user `} language="python" /> Complete UserService Class: User: """Register using Way 2: Modern imprint method.""" existing_user = await User.query().filter(email=user_data.email).first() if existing_user: raise AuthValidationFault(f"A user with this email already exists.") # Imprint does the creation and writes username, email, and password_hash user = await user_data.imprint() return user async def verify_credentials(self, username: str, raw_pass: str) -> User: """Verify username exists and matches hashed password.""" try: user = await User.objects.get(username=username) except Exception: raise AuthValidationFault("Invalid credentials") if not user.is_active: raise AuthValidationFault("User account is inactive") # Validate password is_valid = self.hasher.verify(raw_pass, user.password_hash) if not is_valid: raise AuthValidationFault("Invalid credentials") return user `} language="python" filename="services.py" highlightLines= /> )} ") # .json() is an async coroutine returning the parsed dict/list print(f"-> Registration Output: ") # 2. Log in (CookieJar automatically captures and saves session cookies) login_res = await client.post( "/auth/login", json= ) print(f"-> Login Response Status: ") login_data = await login_res.json() print(f"-> Access Token: ") # 3. Request protected route (client automatically attaches the stored session cookie) me_res = await client.get("/auth/me") print(f"-> Protected Route Profile Status: ") print(f"-> User Profile: ") # 4. Log out logout_res = await client.post("/auth/logout") print(f"-> Logout Response Status: ") print(f"-> Logout Message: ") except HTTPClientFault as exc: print(f"[ERROR] HTTP outbound call failed: (Code: )") if __name__ == "__main__": asyncio.run(run_smoke_test()) `} language="python" filename="smoke_test.py" highlightLines= /> Key Features of aquilia.http AsyncHTTPClient: • Automatic Cookie Management: Built-in CookieJar automatically parses and sends back session cookies in consecutive requests, mimicking browser behaviors perfectly. • Connection Pooling: Managed connections allow highly performant reuse of TCP sockets under host limit locks. • Structured Fault Domains: All outbound HTTP request exceptions map to typed `HTTPClientFault` subclasses, allowing clean error tracking and backoff handling. )} Previous Step Next Step )

### Code Examples
```python
aq add module
```

```python
aq add module auth --route-prefix=/auth -y
```

```python
# modules/auth/models.py
from datetime import datetime
from aquilia.database import Model
from aquilia.models import fields
from aquilia.models import Index, UniqueConstraint


class User(Model):
    """
    SQL database model representing a registered user account.
    """
    id = fields.IntegerField(primary_key=True)
    username = fields.CharField(max_length=150, unique=True, index=True)
    email = fields.CharField(max_length=255, unique=True, index=True)
    password_hash = fields.CharField(max_length=255)
    is_active = fields.BooleanField(default=True)
    created_at = fields.DateTimeField(default=datetime.utcnow)
    last_login = fields.DateTimeField(null=True)

    class Meta:
        table_name = "auth_users"
        # Custom composite index for fast credential checks
        indexes = [
            Index(fields=["username", "is_active"], name="idx_users_username_active")
        ]
        # Multi-column unique constraints
        constraints = [
            UniqueConstraint(fields=["username", "email"], name="uq_user_credentials")
        ]
```



---

## AquiliaServer
**URL**: `https://tubox.cloud/docs/server`

AquiliaServer aquilia.server — Main server orchestration AquiliaServer is the central orchestrator that wires together every subsystem — from Aquilary manifest compilation to ASGI request handling. It is a 4,000+ line class that serves as the single entry point for the entire framework. Server DI DI Containers ASGI ASGI Adapter REG App Registry ENG Controller Engine Constructor Parameter Type Description ))} Initialization Sequence The __init__ method performs the following steps in order. Understanding this sequence is critical for debugging boot issues: Key Attributes Attribute Type Description ) : ( type )} ))} Middleware Setup The _setup_middleware() method builds the middleware stack from configuration. Middleware is added conditionally based on what integrations are enabled: Session & Auth Setup The server supports configuration for sessions using the typed SessionIntegration class: Startup & Shutdown Running the Server Production tip: Use aq serve for production deployments. It runs uvicorn with production-optimized settings (no reload, access logs, worker configuration). Use aq run for development (auto-reload enabled). Debug Mode When debug=True (via config, AQ_DEBUG=true, or RegistryMode.DEV), the server enables: • Debug error pages — ExceptionMiddleware renders rich HTML error pages with tracebacks, request details, and source code context • Verbose logging — Full request/response body logging • Relaxed validation — Missing optional providers don't cause boot failures • Auto-reload — File watcher restarts server on code changes (uvicorn --reload) Related → ASGI Adapter: How Aquilia bridges ASGI and its internal pipeline → Lifecycle: Dependency-ordered startup/shutdown coordination → MiddlewareStack: How middleware ordering works )

### Code Examples
```python
from aquilia.server import AquiliaServer
from aquilia.config import ConfigLoader
from aquilia.aquilary import RegistryMode

server = AquiliaServer(
    manifests=[CoreManifest, UsersManifest],  # List of manifest classes
    config=ConfigLoader(),                     # Optional: custom config loader
    mode=RegistryMode.PROD,                    # DEV, PROD, or TEST
    aquilary_registry=None,                    # Optional: pre-built AquilaryRegistry
)
```

```python
# AquiliaServer.__init__() sequence:

# 1. Load configuration
self.config = config or ConfigLoader()

# 2. Initialize fault engine
self.fault_engine = FaultEngine(debug=self._is_debug())

# 3. Apply fault integration patches to subsystems
from aquilia.faults.integrations import patch_all_subsystems
patch_all_subsystems()

# 4. Build Aquilary registry from manifests
self.aquilary = Aquilary.from_manifests(
    manifests=manifests,
    config=self.config,
    mode=mode,
)

# 5. Create RuntimeRegistry (lazy compilation)
self.runtime = RuntimeRegistry.from_metadata(self.aquilary, self.config)
self.runtime._register_services()  # Populate DI containers immediately

# 6. Register framework services in every DI container
#    - FaultEngine (scope: app)
#    - EffectRegistry (scope: app)

# 7. Create LifecycleCoordinator
self.coordinator = LifecycleCoordinator(self.runtime, self.config)

# 8. Setup middleware stack
#    - ExceptionMiddleware (priority: 1)
#    - FaultMiddleware (priority: 2)
#    - ProxyFixMiddleware (priority: 3)
#    - HTTPSRedirectMiddleware (priority: 4)
#    - ServerRequestScopeMiddleware / VersionMiddleware (priority: 5)
#    - StaticMiddleware (priority: 6)
#    - SecurityHeadersMiddleware (priority: 7)
#    - HSTSMiddleware (priority: 8)
#    - CSPMiddleware (priority: 9)
#    - RequestIdMiddleware (priority: 10)
#    - CORSMiddleware / InspectorMiddleware (priority: 11)
#    - RateLimitMiddleware / ToolbarInjectionMiddleware (priority: 12)
#    - SessionMiddleware / AquilAuthMiddleware (priority: 15)
#    - CSRFMiddleware (priority: 20)
#    - I18nMiddleware (priority: 24)
#    - TemplateMiddleware (priority: 25)
#    - CacheMiddleware (priority: 26)

# 9. Create controller pipeline
#    - ControllerFactory (with base DI container)
#    - ControllerEngine (with fault engine)
#    - ControllerCompiler

# 10. Create ASGI adapter
self.app = ASGIAdapter(
    controller_router=self.controller_router,
    controller_engine=self.controller_engine,
    socket_runtime=self.aquila_sockets,
    middleware_stack=self.middleware_stack,
    server=self,
)
```

```python
# Always added in the pipeline:
ExceptionMiddleware(debug=True)      # Priority 1 — global exception handling
FaultMiddleware(fault_engine)         # Priority 2 — converts fault signals to HTTP responses
ServerRequestScopeMiddleware(...)     # Priority 5 — initializes/tears down request-scoped DI container

# Added if versions configured:
VersionMiddleware(strategy)           # Priority 5 — API version resolution

# Added if sessions/auth configured:
SessionMiddleware(session_engine)     # Priority 15 — loads and saves session state
AquilAuthMiddleware(...)              # Priority 15 — unified auth and identity extraction

# Added if templates configured:
TemplateMiddleware(...)               # Priority 25 — injects template engine and rendering helper

# Added if caching configured:
CacheMiddleware(...)                  # Priority 26 — caches GET responses

# Security & Infrastructure Middleware (via _setup_security_middleware):
ProxyFixMiddleware(...)               # Priority 3 — handles trust-proxy headers
HTTPSRedirectMiddleware(...)          # Priority 4 — redirects HTTP to HTTPS
StaticMiddleware(...)                 # Priority 6 — serves static files directly
SecurityHeadersMiddleware(...)        # Priority 7 — security response headers
HSTSMiddleware(...)                   # Priority 8 — Strict-Transport-Security header
CSPMiddleware(...)                    # Priority 9 — Content-Security-Policy header & nonces
CORSMiddleware(...)                   # Priority 11 — CORS preflight and access control
RateLimitMiddleware(...)              # Priority 12 — sliding window request rate limiting
CSRFMiddleware(...)                   # Priority 20 — CSRF token validation
I18nMiddleware(...)                   # Priority 24 — locale resolution and translating

# Development/Inspector Middleware:
RequestIdMiddleware()                 # Priority 10 — request trace ID generator (default/fallback)
InspectorMiddleware(...)              # Priority 11 — captures debugging statistics
ToolbarInjectionMiddleware(...)      # Priority 12 — injects dev diagnostics toolbar
```



---

## ASGI Adapter
**URL**: `https://tubox.cloud/docs/server/asgi`

ASGI Adapter aquilia.asgi — Bridging ASGI to Aquilia internals The ASGIAdapter is a high-performance 777-line class designed for maximum throughput and security. It translates raw ASGI connection scopes and event streams into Aquilia's Request and Response abstractions, manages transactional dependency injection scopes, executes the middleware stack, and handles the ASGI lifespan handshake. 1 ASGI Call 2 Ctx Pool 3 Version strip 4 Middleware 5 Action The ASGI Specification ASGI (Asynchronous Server Gateway Interface) defines the standard interface between async-capable Python web servers and web applications. Aquilia is an async-native, pure ASGI application that runs on any compliant server (such as Uvicorn, Hypercorn, or Granian). None: """ scope: Dictionary containing connection metadata (type, path, method, headers, etc.) receive: Async callable to receive incoming ASGI events (HTTP request bodies, WebSocket messages) send: Async callable to push outgoing ASGI events to the client """ ...`} language="python" /> ASGIAdapter Architecture The adapter uses `__slots__` to eliminate per-instance dictionary overhead and caches references to subsystems to avoid expensive attribute lookups during hot paths: Core Adapter Operations 1. Zero-Allocation Context Pooling To prevent garbage collection overhead under high request concurrency, the adapter uses a lock-free RequestCtx object pool (_ctx_pool). Instead of allocating a new context object on every request, the adapter acquires a recycled context, resets its fields in-place, and releases it back to the pool once the response is sent. 2. API Version & Path Prefix Pre-Resolution API versioning can affect the routing table. To resolve this, the adapter calls _resolve_route_inputs() before route matching. It evaluates version headers/queries, strips structural URL prefixes (e.g., stripping /v2 from /v2/users), and passes the cleaned path to the Router , ensuring version middleware can negotiate correctly without route mismatches. 3. RFC-Compliant Auto-HEAD Fallback In compliance with the HTTP/1.1 specification (RFC 7231 §4.3.2), if a client sends a HEAD request but no explicit HEAD handler is registered on the matched path, the adapter automatically matches the route's GET handler, runs the full middleware and validation logic, and then strips the body from the final response before sending headers. 4. Structured 405 Method Not Allowed Responses If a path matches a route but does not support the requested HTTP method, the adapter queries alternative methods, automatically sets a valid Allow header, and generates a structured error (returning styled HTML for browsers or structured JSON for APIs based on the Accept header). Built-in Performance-Optimized Health Endpoint The health endpoint (/_health and /health) is handled directly inside the ASGI adapter, bypassing the entire middleware stack to minimize CPU overhead. • Method Restricting: Bypassed paths are restricted to GET and HEAD requests; other methods immediately return a 405 Method Not Allowed response. • Subsystem Diagnostics: Integrates with the central HealthRegistry to query status details for registered subsystems (database, cache, task workers, mail, and storage). • Security Hardening: To satisfy OWASP compliance, the health endpoint manually applies strict security headers (e.g., cache-control: no-store, x-content-type-options: nosniff, x-frame-options: DENY) since it bypasses normal security middleware. Lifespan Startup Guards & Error Sanitization The ASGI lifespan protocol coordinates application startup and shutdown. Aquilia hardens this phase with two critical behaviors: Database Not Ready Guard (SystemExit) If a module raises DatabaseNotReadyError (which inherits from SystemExit) during startup, the adapter catches the warning, logs it, and sends lifespan.startup.complete anyway. This prevents ASGI servers (like Uvicorn) from logging a fatal crash and disabling lifespan events, allowing the server to boot into a degraded/retry state. OWASP Error Sanitization For standard exceptions raised during startup, the adapter logs the full traceback inside the application logs but returns a sanitized message ("Server startup failed") back to the ASGI server's startup.failed event, preventing stack traces or database connection string secrets from leaking into system logs. Production Deployment Deploy Aquilia using uvicorn or granian workers. Ensure lifespan is explicitly enabled. Uvicorn (Standard Python Worker) Granian (High-Performance Rust-based ASGI Server) → Lifecycle: Startup/shutdown coordination → Request: The Request object in depth → MiddlewareStack: How the chain is built and ordered )

### Code Examples
```python
# The standard ASGI 3.0 application signature:
async def application(
    scope: dict[str, Any], 
    receive: Callable[[], Awaitable[dict[str, Any]]], 
    send: Callable[[dict[str, Any]], Awaitable[None]]
) -> None:
    """
    scope:   Dictionary containing connection metadata (type, path, method, headers, etc.)
    receive: Async callable to receive incoming ASGI events (HTTP request bodies, WebSocket messages)
    send:    Async callable to push outgoing ASGI events to the client
    """
    ...
```

```python
class ASGIAdapter:
    """ASGI application adapter that converts ASGI events to Aquilia Request/Response."""

    __slots__ = (
        "controller_router",
        "controller_engine",
        "middleware_stack",
        "server",
        "socket_runtime",
        "logger",
        "_cached_middleware_chain",
        "_default_container",
        "_debug",
        "_has_routes_cache",
        "_server_runtime",
    )

    def __init__(
        self,
        controller_router: ControllerRouter,
        controller_engine: Any,
        middleware_stack: MiddlewareStack,
        server: Any | None = None,
        socket_runtime: Any | None = None,
    ):
        self.controller_router = controller_router
        self.controller_engine = controller_engine
        self.middleware_stack = middleware_stack
        self.server = server
        self.socket_runtime = socket_runtime
        self.logger = logging.getLogger("aquilia.asgi")
        self._cached_middleware_chain = None  # Built once and cached
```

```python
# Inside handle_http:
ctx = _ctx_pool.acquire(
    request=request,
    identity=None,
    session=None,
    container=di_container,
)
try:
    response = await handler(request, ctx)
finally:
    _ctx_pool.release(ctx)
```



---

## Lifecycle
**URL**: `https://tubox.cloud/docs/server/lifecycle`

Lifecycle aquilia.lifecycle — Dependency-ordered startup and shutdown The LifecycleCoordinator manages application startup and shutdown phases in strict dependency order. It ensures that service containers are prepared, global and module-level hooks are executed sequentially, and resources are rolled back or cleaned up safely in reverse order on boot failures. INIT 1. Wire Config GLOB 2. Global Startup TOPO 3. Dependency Sort DI 4. DI Container Startup 5. READY Lifecycle Phases The application transitions through distinct states defined in the LifecyclePhase enum: return ( ) })} LifecycleCoordinator The coordinator is instantiated during AquiliaServer.__init__(). It retrieves module dependency configurations, tracks started applications, and fires events to registered observers: Lifecycle Hook Execution Flow 1. Startup Sequence (Topological Order) When startup() is called, the coordinator: Fires the global workspace-level on_startup hook (if defined in self.config), passing the base DI container. Iterates through module application contexts (runtime.meta.app_contexts), which are pre-sorted in topological dependency order. For each module: starts its DI container (executes DI provider startup events) and resolves and executes the module's on_startup(config_ns, container) hook. Appends the booted module to started_apps for rollback tracking. 2. Shutdown Sequence (Reverse Dependency Order) teardown is executed in reverse order of startup. If App A boots before App B, then App B's on_shutdown runs before App A's. This ensures dependent resources remain active while their consumers tear down. Graceful Error Handling: Unlike startup, exceptions raised during shutdown do not halt the process. The coordinator catches the error, logs it as a warning, and continues running the remaining teardown hooks to ensure best-effort resource cleanup. 3. Automatic Startup Rollback If any module fails to startup, the coordinator flags the phase as LifecyclePhase.ERROR, logs the traceback, and initiates an automatic rollback. It executes the shutdown sequence for all modules listed in started_apps in reverse order, ensuring no orphaned resources remain active before propagating a LifecycleError. Controller Lifecycle Hooks Controllers with instantiation_mode = "singleton" can hook into startup and shutdown events directly. All controllers, regardless of mode, support per-request hooks: None: """Called once when the server boots.""" self.client = await self.init_client() async def on_shutdown(self, ctx: RequestCtx) -> None: """Called once during server shutdown.""" await self.client.close() async def on_request(self, ctx: RequestCtx) -> None: """Called before EVERY incoming request routed to this controller.""" ctx.state["req_start"] = time.monotonic() async def on_response(self, ctx: RequestCtx, response: Response) -> Response: """Called after EVERY request. Allows altering response headers/body.""" duration = time.monotonic() - ctx.state["req_start"] response.headers["X-Process-Time"] = f" s" return response`} language="python" /> Hook Method Trigger Frequency Supported Modes ))} The LifecycleManager Context Manager For script execution, testing, or server wrappers, the LifecycleManager class exposes an async context manager. This enforces startup on entry and guarantees cleanup on block exit, even if unhandled exceptions are raised: Central Observability Observers The AquiliaServer registers two default observers on the coordinator: • Fault Observer ( _lifecycle_fault_observer): Intercepts error events and records them in the structured FaultEngine database. • Trace Observer ( _lifecycle_trace_observer): Records all successful transitions and phase changes directly to the .aquilia/lifecycle.log journal. → AquiliaServer: Full server orchestration → DI Lifecycle: Container-level lifecycle management )

### Code Examples
```python
class LifecyclePhase(Enum):
    INIT = "init"           # Server initialized, dependencies wired
    STARTING = "starting"   # startup() called, boot hooks executing
    READY = "ready"         # All boot hooks completed, server accepting traffic
    STOPPING = "stopping"   # shutdown() called, teardown hooks executing
    STOPPED = "stopped"     # All teardown hooks completed, server down
    ERROR = "error"         # A lifecycle hook crashed during startup
```

```python
class LifecycleCoordinator:
    """Coordinates application lifecycle across multiple apps/modules."""

    def __init__(self, runtime: Any, config: ConfigLoader | None = None):
        self.runtime = runtime
        self.config = config
        self.phase = LifecyclePhase.INIT
        self.started_apps: list[str] = []  # Tracks successfully booted modules
        self.event_handlers: list[Callable[[LifecycleEvent], None]] = []
        self.logger = logger

    def on_event(self, handler: Callable[[LifecycleEvent], None]):
        """Register a callback that receives LifecycleEvent notifications."""
        self.event_handlers.append(handler)
```

```python
# Step-by-step app-level boot inside _startup_app():
# 1. Start DI container (runs provider startup hooks)
if di_container and hasattr(di_container, "startup"):
    await di_container.startup()

# 2. Resolve and run startup hook
hook = self._resolve_hook(ctx.on_startup)
if hook:
    if inspect.iscoroutinefunction(hook):
        await hook(config_ns, di_container)
    else:
        hook(config_ns, di_container)
```



---

## Configuration System
**URL**: `https://tubox.cloud/docs/config`

Configuration System aquilia.pyconfig — Pure Python, zero YAML Aquilia's configuration system is pure Python. There is no YAML, no TOML, no JSON. Everything — application structure, modules, integrations, and environment-specific settings — lives in a single workspace.py file. AquilaConfig subclasses carry the environment config; the Workspace builder wires it all together. workspace.py single source of truth , , , , ].map(( , i) => ( ))} Why pure Python config? , , , ].map(( ) => ( ))} workspace.py — the single file Everything lives in workspace.py at the project root. The AquilaConfig subclasses declare environment-specific settings with Env bindings and Secret fields. The Workspace builder wires modules and typed integration dataclasses. At runtime, .env_config(BaseEnv) reads AQ_ENV to select the right subclass automatically. ConfigLoader — the internal bridge When the server starts, AquilaConfig.to_loader() converts your class hierarchy into a ConfigLoader instance that all internal subsystems read from. You never instantiate ConfigLoader directly — the framework does it during boot. You interact with it only in advanced scenarios (tests, plugins, custom CLI commands). Value resolution precedence When multiple sources define the same key, this order wins. Higher rows always take priority — the process environment (Docker, Kubernetes, CI/CD) always wins over source defaults. Priority Source How and loads before first access'], ['3', 'AquilaConfig literal fields', 'Class-level assignments in your section subclasses'], ['4 — Lowest', 'Built-in defaults', 'Aquilia\'s defaults inside AquilaConfig.Server, .Auth, .Database, etc.'], ].map(([priority, source, how], i) => ( ))} Environment selection at runtime .env_config(BaseEnv) scans all subclasses of BaseEnv and picks the one whose env attribute matches the AQ_ENV environment variable. If AQ_ENV is not set, it falls back to "dev". Inspecting config values Use .to_dict() to see the fully-resolved, serialised config at any point. All Env descriptors are resolved and all Secret values are revealed in the dict — handle it accordingly. Testing config Use AquilaConfig.clear_all_caches() between tests to reset all resolved caches and the dotenv loader state. Combine with monkeypatch.setenv() to simulate different environments. ))} )

### Code Examples
```python
# workspace.py — everything in one file
from aquilia import Workspace, Module
from aquilia.pyconfig import AquilaConfig, Env, Secret
from aquilia.integrations import (
    DatabaseIntegration,
    AuthIntegration,
    CacheIntegration,
    SessionIntegration,
    OpenAPIIntegration,
    MailIntegration, SmtpProvider, MailAuth,
    TasksIntegration,
    CorsIntegration,
)

# ─── Environment Config ─────────────────────────────────────────────────────

class BaseEnv(AquilaConfig):
    """Shared baseline — all environments inherit from this."""

    class server(AquilaConfig.Server):
        host    = "127.0.0.1"
        port    = Env("PORT", default=8000, cast=int)
        workers = 1

    class auth(AquilaConfig.Auth):
        secret_key = Secret(env="AQ_SECRET_KEY", required=True)
        algorithm  = "HS256"

    class database(AquilaConfig.Database):
        url = Env("DATABASE_URL", default="sqlite:///dev.db")

class DevEnv(BaseEnv):
    env = "dev"

    class server(BaseEnv.server):
        reload = True
        debug  = True

class ProdEnv(BaseEnv):
    env = "prod"

    class server(BaseEnv.server):
        host    = "0.0.0.0"
        workers = Env("WEB_WORKERS", default=4, cast=int)
        timeout_graceful_shutdown = 30

    class auth(BaseEnv.auth):
        password_hasher = AquilaConfig.PasswordHasher.argon2id(time_cost=3, memory_cost=131072)

# ─── Application Structure ──────────────────────────────────────────────────

workspace = (
    Workspace("myapp", version="1.0.0")
    .env_config(BaseEnv)                      # reads AQ_ENV → picks DevEnv / ProdEnv

    .module(Module("auth").route_prefix("/auth"))
    .module(Module("users").route_prefix("/users").depends_on("auth"))
    .module(Module("blog").route_prefix("/blog"))

    .integrate(DatabaseIntegration(
        url=Env("DATABASE_URL", default="sqlite:///app.db"),
        auto_migrate=True,
        pool_size=10,
    ))
    .integrate(AuthIntegration(
        secret_key=Secret(env="AQ_SECRET_KEY", required=True).reveal(),
        algorithm="HS256",
        access_token_ttl_minutes=60,
        refresh_token_ttl_days=30,
    ))
    .integrate(CacheIntegration(backend="redis", redis_url="redis://localhost:6379/0"))
    .integrate(OpenAPIIntegration(title="My App API", version="1.0.0"))
)
```

```python
# Aquilia does this internally during boot.
# You only need this for custom tooling or tests.

loader = ProdEnv.to_loader()

# Dot-path access
port    = loader.get("server.port")      # → int
db_url  = loader.get("database.url")    # → str

# Typed subsystem accessors
auth_cfg  = loader.get_auth_config()
sess_cfg  = loader.get_session_config()
cache_cfg = loader.get_cache_config()

# Invalidate cache after env changes (useful in tests)
ProdEnv.invalidate_cache()
AquilaConfig.clear_all_caches()         # clears all subclass caches + resets dotenv state
```

```python
# In workspace.py:
workspace = Workspace("myapp").env_config(BaseEnv)

# At runtime the framework calls:
#   AQ_ENV=prod → uses ProdEnv
#   AQ_ENV=dev  → uses DevEnv  (also the default if unset)

# You can also select manually (useful in scripts and tests):
loader = BaseEnv.from_env_var("AQ_ENV", default="dev").to_loader()
# or by explicit class:
loader = ProdEnv.to_loader()
# or by name:
loader = AquilaConfig.for_env("prod").to_loader()   # → resolves ProdEnv
```



---

## Workspace Builder
**URL**: `https://tubox.cloud/docs/config/workspace`

Workspace Builder aquilia.workspace — Workspace() fluent builder Workspace is the top-level fluent builder that defines your entire application — its name, modules, integrations, and environment config. Everything chains off a single Workspace("name") call and lives in workspace.py at the project root. Minimal example Workspace() constructor Param Default Description )} .env_config() Wires an AquilaConfig base class into the workspace. At runtime, the framework reads the AQ_ENV environment variable and selects the matching subclass automatically. The config is then converted to a ConfigLoader and made available to all subsystems. .module() Registers a Module in the workspace. A module is a logical boundary that groups controllers, services, routes, models, and middleware under a single URL prefix and optional fault domain. Each Module builder is converted to a ModuleConfig internally. You can register as many modules as you need — they are isolated from each other unless explicitly declared as dependencies. .integrate() Adds a typed integration dataclass to the workspace. Pass instances from aquilia.integrations — each one has __post_init__ validation and a _integration_type field the framework uses for routing. There is no old-style Integration.database() static method — use the typed dataclasses directly. Combining env_config with integrations .env_config() controls the environment-level settings (server, auth tokens, DB URL) through AquilaConfig subclasses. .integrate() controls the subsystem behaviour (connection pools, middleware, logging). They are complementary — use both together for the cleanest production setup. .security() — high-level flags High-level flags that enable entire middleware categories with sensible defaults. For fine-grained control (custom CORS origins, CSRF exemptions, rate-limit algorithms), use the typed integration dataclasses via .integrate() instead. Sessions shorthand You can also use .sessions() as a shorthand instead of .integrate(SessionIntegration(...)). Both are equivalent. .mlops() Shorthand to enable the Aquilia MLOps platform — model registry, serving, drift detection, and lineage tracking. Equivalent to .integrate(MlopsIntegration(...)). Full production workspace ))} )

### Code Examples
```python
# workspace.py
from aquilia import Workspace, Module
from aquilia.pyconfig import AquilaConfig, Env, Secret
from aquilia.integrations import DatabaseIntegration, AuthIntegration, OpenAPIIntegration

class BaseEnv(AquilaConfig):
    class server(AquilaConfig.Server):
        host = "127.0.0.1"
        port = Env("PORT", default=8000, cast=int)

    class auth(AquilaConfig.Auth):
        secret_key = Secret(env="AQ_SECRET_KEY", required=True)

workspace = (
    Workspace("myapp", version="1.0.0")
    .env_config(BaseEnv)
    .module(Module("api").route_prefix("/api"))
    .integrate(DatabaseIntegration(url=Env("DATABASE_URL", default="sqlite:///app.db")))
    .integrate(AuthIntegration(secret_key="dev-secret"))
    .integrate(OpenAPIIntegration(title="My API", version="1.0.0"))
)
```

```python
from aquilia import Workspace

workspace = Workspace(
    name="myapp",               # Required. Used in logging, traces, and OpenAPI metadata
    version="1.0.0",            # Optional. Shown in OpenAPI spec and admin panel
    description="My App",       # Optional. Human-readable description
)
```

```python
from aquilia import Workspace
from aquilia.pyconfig import AquilaConfig, Env, Secret

class BaseEnv(AquilaConfig):
    class server(AquilaConfig.Server):
        host    = "127.0.0.1"
        port    = Env("PORT", default=8000, cast=int)
        workers = 1

class DevEnv(BaseEnv):
    env = "dev"
    class server(BaseEnv.server):
        reload = True
        debug  = True

class ProdEnv(BaseEnv):
    env = "prod"
    class server(BaseEnv.server):
        host    = "0.0.0.0"
        workers = Env("WEB_WORKERS", default=4, cast=int)
        timeout_keep_alive = 30

workspace = (
    Workspace("myapp")
    .env_config(BaseEnv)   # AQ_ENV=prod → uses ProdEnv, AQ_ENV=dev → uses DevEnv
)
```



---

## Module Builder
**URL**: `https://tubox.cloud/docs/config/module`

Module Builder aquilia.config_builders.Module — Application unit configuration The Module class is a fluent builder for defining isolated application units within a workspace. Each module represents a self-contained logical boundary that groups controllers, services, routes, models, serializers, and middleware under a single, explicit configuration contract. ModuleConfig Dataclass The Module builder produces a ModuleConfig dataclass via .build(). This dataclass is what Workspace.to_dict() serializes into the final config. @dataclass class ModuleConfig: """Module configuration produced by Module.build().""" name: str = "" version: str = "0.1.0" description: str = "" fault_domain: str = "" route_prefix: str = "" depends_on: List[str] = field(default_factory=list) controllers: List[str] = field(default_factory=list) routes: List[str] = field(default_factory=list) services: List[str] = field(default_factory=list) providers: List[str] = field(default_factory=list) middlewares: List[str] = field(default_factory=list) socket_controllers: List[str] = field(default_factory=list) models: List[str] = field(default_factory=list) serializers: List[str] = field(default_factory=list) tags: List[str] = field(default_factory=list) auto_discover: Optional[str] = None database: Optional[Dict[str, Any]] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary format.""" ... Field Type Default Description ))} Module Builder The Module class wraps ModuleConfig in a fluent builder pattern. Every method returns self for chaining. class Module: """Fluent module builder.""" def __init__(self, name: str, version: str = "0.1.0", description: str = ""): self._config = ModuleConfig( name=name, version=version, description=description, ) def build(self) -> ModuleConfig: """Build module configuration.""" return self._config .auto_discover() Tells the Aquilary discovery system to scan the specified directory for controllers, services, routes, models, and other components. This is the most common way to register components — you point the module at a directory and Aquilia finds everything. def auto_discover(self, path: str) -> "Module": """ Set auto-discovery path. The Aquilary discovery system will scan this directory for: - Controllers (classes inheriting from Controller) - Services (classes decorated with @service) - Routes (functions decorated with @route) - Models (.amdl files) - Serializers (classes inheriting from Serializer) """ self._config.auto_discover = path return self # Scan apps/users/ for all components Module("users").auto_discover("apps/users") # Combined with explicit registrations Module("users") .auto_discover("apps/users") .register_services("ExtraService") # Add extras not in the scan path .route_prefix() Sets a URL prefix for all controllers and routes in this module. Prefixed before the controller's own prefix attribute. def route_prefix(self, prefix: str) -> "Module": """Set URL prefix for all routes in this module.""" self._config.route_prefix = prefix return self # Example: Module prefix + Controller prefix # Module("users").route_prefix("/api/v1") # class UserController(Controller): # prefix = "/users" # # Final route: /api/v1/users/ .fault_domain() Assigns this module to a fault isolation domain. Faults raised within this module are scoped to its domain, enabling domain-specific error handlers and preventing fault propagation across module boundaries. def fault_domain(self, domain: str) -> "Module": """Set fault isolation domain.""" self._config.fault_domain = domain return self # Usage: Module("payments") .fault_domain("payments") # Faults scoped to "payments" domain .route_prefix("/payments") .depends_on() Declares dependencies on other modules. This is used for startup ordering and dependency validation — if module A depends on module B, B is initialized first. def depends_on(self, *modules: str) -> "Module": """Declare module dependencies.""" self._config.depends_on = list(modules) return self # Usage: Module("orders") .depends_on("users", "catalog", "payments") .route_prefix("/orders") .tags() Assigns OpenAPI tags to all controllers in this module. Tags are used for grouping endpoints in the Swagger UI and ReDoc documentation. def tags(self, *tags: str) -> "Module": """Set OpenAPI tags for this module.""" self._config.tags = list(tags) return self # Usage: Module("catalog") .tags("Products", "Categories", "Search") .route_prefix("/catalog") Registration Methods These methods explicitly register component names. They accept *args (variadic string names) and return self for chaining. Use these when auto-discovery is insufficient or when you need explicit control over what's registered. Method Signature Registers To ))} # All registration methods follow this pattern: def register_controllers(self, *names: str) -> "Module": """Register controller class names.""" self._config.controllers = list(names) return self def register_services(self, *names: str) -> "Module": """Register service class names.""" self._config.services = list(names) return self # ... same pattern for all others Module("users") .register_controllers("UserController", "ProfileController", "AdminController") .register_services("UserService", "AuthService", "TokenService") .register_providers("DatabaseProvider", "CacheProvider") .register_routes("health_check", "status") .register_sockets("ChatController") .register_middlewares("TenantMiddleware") .register_models("models/user.amdl", "models/profile.amdl") .register_serializers("UserSerializer", "ProfileSerializer") Note: Registration methods replace the list (they don't append). Calling .register_controllers("A") then .register_controllers("B") results in only ["B"]. Include all names in a single call. .database() Configures a module-specific database. This overrides the workspace-level database for all models and queries within this module. def database( self, url: str = "sqlite:///db.sqlite3", auto_connect: bool = True, auto_create: bool = True, auto_migrate: bool = False, migrations_dir: str = "migrations", **kwargs, ) -> "Module": Parameter Type Default Description ))} workspace = ( Workspace("multi-db-app") # Workspace-level default database .database(url="postgresql://main-db/app") # Module with its own database .module( Module("analytics") .route_prefix("/analytics") .database( url="postgresql://analytics-db/analytics", auto_connect=True, auto_create=True, pool_size=10, ) .register_models("models/analytics.amdl") ) # Module using the default database .module( Module("users") .route_prefix("/users") # No .database() → inherits workspace-level DB ) ) .build() & Serialization .build() returns the underlying ModuleConfig dataclass. This is called automatically by Workspace.module(). The ModuleConfig.to_dict() method serializes it for the config pipeline: # Module("users") # .route_prefix("/users") # .auto_discover("apps/users") # .fault_domain("users") # .tags("Users") # .register_controllers("UserController") # .register_services("UserService") # .build().to_dict() Complete Module Examples # Just a name and auto-discovery — Aquilia finds everything Module("blog").auto_discover("apps/blog") # Full control over what's registered Module("users", version="1.2.0", description="User management") .route_prefix("/api/v1/users") .fault_domain("identity") .depends_on("auth") .tags("Users", "Identity") .register_controllers("UserController", "ProfileController", "AvatarController") .register_services("UserService", "ProfileService", "EmailVerificationService") .register_providers("UserRepository", "ProfileRepository") .register_serializers("UserSerializer", "ProfileSerializer", "AvatarSerializer") .register_models("models/user.amdl", "models/profile.amdl") .register_middlewares("TenantIsolationMiddleware") .database( url="postgresql://identity-db/users", auto_migrate=True, pool_size=15, ) # Discover most things, explicitly add edge cases Module("orders") .auto_discover("apps/orders") # Finds controllers, services, etc. .route_prefix("/orders") .fault_domain("commerce") .depends_on("users", "catalog", "payments") .tags("Orders", "Commerce") .register_providers("StripePaymentProvider") # Not in apps/orders/ .register_middlewares("OrderValidationMiddleware") YAML Equivalent The same module configuration in YAML format: modules: - name: users version: "1.2.0" description: User management route_prefix: /api/v1/users fault_domain: identity depends_on: - auth tags: - Users - Identity auto_discover: apps/users controllers: - UserController - ProfileController services: - UserService - ProfileService models: - models/user.amdl - models/profile.amdl database: url: postgresql://identity-db/users auto_connect: true auto_migrate: true pool_size: 15 ← Workspace Builder Integrations )

### Code Examples
```python
@dataclass
class ModuleConfig:
    """Module configuration produced by Module.build()."""
    name: str = ""
    version: str = "0.1.0"
    description: str = ""
    fault_domain: str = ""
    route_prefix: str = ""
    depends_on: List[str] = field(default_factory=list)
    controllers: List[str] = field(default_factory=list)
    routes: List[str] = field(default_factory=list)
    services: List[str] = field(default_factory=list)
    providers: List[str] = field(default_factory=list)
    middlewares: List[str] = field(default_factory=list)
    socket_controllers: List[str] = field(default_factory=list)
    models: List[str] = field(default_factory=list)
    serializers: List[str] = field(default_factory=list)
    tags: List[str] = field(default_factory=list)
    auto_discover: Optional[str] = None
    database: Optional[Dict[str, Any]] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary format."""
        ...
```

```python
class Module:
    """Fluent module builder."""
    
    def __init__(self, name: str, version: str = "0.1.0", description: str = ""):
        self._config = ModuleConfig(
            name=name,
            version=version,
            description=description,
        )
    
    def build(self) -> ModuleConfig:
        """Build module configuration."""
        return self._config
```

```python
def auto_discover(self, path: str) -> "Module":
    """
    Set auto-discovery path.
    
    The Aquilary discovery system will scan this directory for:
    - Controllers (classes inheriting from Controller)
    - Services (classes decorated with @service)
    - Routes (functions decorated with @route)
    - Models (.amdl files)
    - Serializers (classes inheriting from Serializer)
    """
    self._config.auto_discover = path
    return self
```



---

## Integrations
**URL**: `https://tubox.cloud/docs/config/integrations`

Integrations aquilia.integrations — typed subsystem configuration dataclasses Every subsystem in Aquilia is configured through a typed @dataclass — one class per concern. Each integration is passed to Workspace.integrate(), has __post_init__ validation, full IDE autocompletion, and a .to_dict() method that serialises into the format the runtime expects. How integrations work Import the typed dataclasses from aquilia.integrations and pass instances to .integrate(). The Workspace builder inspects the _integration_type field on each dataclass to route it to the correct subsystem. All available integrations Class Module Purpose ))} DatabaseIntegration Accepts either a url string or a typed config object (SqliteConfig, PostgresConfig). Controls the connection pool, auto-migration, and model scanning directories. Field Default Description )} AuthIntegration Configures JWT token signing, store backend, and session security policy. SessionIntegration Composable session config — a policy object defines TTL and idle behaviour, a store backend determines persistence, and a transport handles cookie or header delivery. All three default to sensible values when omitted. CacheIntegration Selects the cache backend and tunes the key settings, eviction policy, and optional two-tier (composite) caching. MailIntegration Supports SMTP, AWS SES, SendGrid, file-based, and console (dev) providers. MailAuth.plain() handles credentials; MailAuth.oauth2() handles OAuth2 flows. TasksIntegration Configures the background task worker pool — concurrency, retry policy, scheduler tick rate, and dead-letter queue size. OpenAPIIntegration Drives automatic OpenAPI spec generation and serves Swagger UI at /docs and ReDoc at /redoc. Security integrations CORS, CSRF, CSP, and rate-limiting are each separate integrations so you can tune them independently or disable any one without touching the others. TemplatesIntegration AdminIntegration Other integrations ))} )

### Code Examples
```python
from aquilia import Workspace
from aquilia.integrations import (
    DatabaseIntegration,
    AuthIntegration,
    CacheIntegration,
    SessionIntegration,
    OpenAPIIntegration,
    MailIntegration, SmtpProvider, MailAuth,
    TasksIntegration,
    CorsIntegration,
    CsrfIntegration,
    RateLimitIntegration,
    CspIntegration,
    TemplatesIntegration,
    StorageIntegration,
    I18nIntegration,
    LoggingIntegration,
    StaticFilesIntegration,
    VersioningIntegration,
    AdminIntegration, AdminModules,
)

workspace = (
    Workspace("myapp")
    .integrate(DatabaseIntegration(url="sqlite:///app.db"))
    .integrate(AuthIntegration(secret_key="my-secret", access_token_ttl_minutes=60))
    .integrate(OpenAPIIntegration(title="My API", version="1.0.0"))
    .integrate(CorsIntegration(allow_origins=["https://myapp.com"]))
    # ... more integrations
)
```

```python
from aquilia.integrations import DatabaseIntegration
from aquilia.pyconfig import Env

# ── URL-based (simplest) ──────────────────────────────────────────────────
workspace.integrate(DatabaseIntegration(
    url="sqlite:///app.db",         # or Env("DATABASE_URL", required=True)
))

# ── Production Postgres ───────────────────────────────────────────────────
workspace.integrate(DatabaseIntegration(
    url=Env("DATABASE_URL", required=True),
    auto_connect=True,
    auto_create=True,
    auto_migrate=True,              # runs migrations at startup
    migrations_dir="migrations",
    pool_size=20,
    echo=False,                     # True → logs every SQL statement
    scan_dirs=["models"],           # sub-dirs to scan for Model subclasses
))

# ── Typed config object ───────────────────────────────────────────────────
from aquilia.db.configs import PostgresConfig
workspace.integrate(DatabaseIntegration(
    config=PostgresConfig(
        host="db.internal",
        port=5432,
        name="myapp_prod",
        user="app",
        password=Env("DB_PASSWORD", required=True),
    ),
    pool_size=10,
    auto_migrate=True,
))
```

```python
from aquilia.integrations import AuthIntegration
from aquilia.pyconfig import Secret

workspace.integrate(AuthIntegration(
    enabled=True,
    store_type="memory",            # "memory" | "redis" | "database"
    secret_key=Secret(env="AQ_SECRET_KEY", required=True).reveal(),
    algorithm="HS256",              # HS256/HS384/HS512 (stdlib) or RS256/ES256/EdDSA (cryptography pkg)
    issuer="myapp",
    audience="myapp-api",
    access_token_ttl_minutes=60,
    refresh_token_ttl_days=30,
    require_auth_by_default=False,  # True → all routes require JWT unless @public
))
```



---

## AquilaConfig
**URL**: `https://tubox.cloud/docs/config/pyconfig`

import from 'lucide-react' AquilaConfig aquilia.pyconfig — Python-native, zero-YAML environment configuration AquilaConfig is the base class for environment-specific configuration. Subclass it once per environment, override only what changes, and use Env to bind fields to OS environment variables or Secret to protect sensitive values. All of this lives directly in workspace.py. Why Python-native config , , , ].map(( ) => ( ))} AquilaConfig — layered inheritance Subclass AquilaConfig once per deployment environment. The env attribute is the identifier — AQ_ENV=prod selects the class whose env = "prod". Only override the nested sections that change between environments; everything else is inherited from the base class automatically. Built-in section types Each section type provides typed defaults, IDE hover docs, and a clean interface for overriding only what changes. Extend any of them inside your AquilaConfig subclass. Section Key fields Purpose ))} AquilaConfig.Server — full reference Every attribute maps directly to a uvicorn.Config parameter and is forwarded automatically. No glue code required — adding a new field here is all you need. Env — live environment variable binding Env is a descriptor that reads from os.environ at attribute access time. Values already in the process environment (from Docker, Kubernetes, or CI/CD) always win over source-code defaults. The dotenv loader is triggered automatically on first access — you never call load_dotenv() manually. Auto-cast rules (no cast= specified) Raw string value Resolved Python value Type \'', ' ', 'dict (JSON)'], ['"hello"', '"hello"', 'str (fallback)'], ].map(([raw, out, t], i) => ( ))} Secret — redacted sensitive values Secret wraps any sensitive value — API keys, database passwords, signing keys. The underlying value never appears in repr(), str(), log output, or serialised config until you call .reveal() deliberately. The resolution order is: env var → literal value → default. — safe to log # >>> repr(BaseEnv.auth.secret_key) # "Secret(env='AQ_SECRET_KEY', *required*)" # Only .reveal() returns the actual value key = BaseEnv.auth.secret_key.reveal() # → "actual-key-value-from-env" # Properties is_required = BaseEnv.auth.secret_key.is_required # → True env_var_name = BaseEnv.auth.secret_key.env_name # → "AQ_SECRET_KEY"`} /> Never commit literal Secret values. Secret(value="...") is for local dev only. In staging and production always point to an env var: Secret(env="MY_KEY", required=True). AquilaConfig.PasswordHasher Controls the password hashing algorithm used by the auth subsystem. Class-method shortcuts provide sensible defaults for each algorithm. Algorithm Factory method Notes ))} AquilaConfig.Signing — cryptographic signing Controls the aquilia.signing module that backs session cookies, CSRF tokens, one-time activation links, cache integrity checks, and signed cookies. Each subsystem uses an isolated namespace salt so cross-subsystem token reuse is cryptographically impossible. @section — custom config grouping The @section decorator marks any arbitrary nested class as a named config section included in the serialised to_dict() output. Use it for app-specific subsystems that don't map to a built-in section type. AquilaConfig.Dotenv — file loading policy Control exactly which .env files are loaded and in what order. Define a nested Dotenv class inside your AquilaConfig subclass. AquilaConfig.Apps — per-module namespaces Place module-specific settings inside a nested class named after the module. Access them via config.apps.<module_name>.<field> inside that module's services or controllers. Runtime API — to_dict, to_loader, get, for_env Testing patterns ))} )

### Code Examples
```python
from aquilia import Workspace, Module
from aquilia.pyconfig import AquilaConfig, Env, Secret

# ─── Shared baseline ────────────────────────────────────────────────────────
class BaseEnv(AquilaConfig):
    """Shared across all environments — only changed fields are redefined."""

    class server(AquilaConfig.Server):
        host    = "127.0.0.1"
        port    = Env("PORT", default=8000, cast=int)
        workers = 1
        timeout_keep_alive = 5

    class auth(AquilaConfig.Auth):
        secret_key = Secret(env="AQ_SECRET_KEY", required=True)
        algorithm  = "HS256"            # Zero-dependency HMAC-SHA-256
        access_token_ttl_minutes = 60
        refresh_token_ttl_days   = 30

    class database(AquilaConfig.Database):
        url         = Env("DATABASE_URL", default="sqlite:///dev.db")
        pool_size   = 5
        auto_migrate = False

    class cache(AquilaConfig.Cache):
        backend     = "memory"
        default_ttl = 300

    class di(AquilaConfig.DI):
        scope_enforcement   = "warn"    # "warn" | "raise" | "off"
        parallel_resolution = False

    class signing(AquilaConfig.Signing):
        secret = Secret(env="AQ_SECRET_KEY", required=True)

# ─── Development overrides ───────────────────────────────────────────────────
class DevEnv(BaseEnv):
    env = "dev"                         # selected by AQ_ENV=dev

    class server(BaseEnv.server):
        reload = True
        debug  = True
        log_level = "debug"

    class di(BaseEnv.di):
        diagnostics_enabled = True      # trace every resolution in dev

# ─── Staging overrides ───────────────────────────────────────────────────────
class StagingEnv(BaseEnv):
    env = "staging"                     # selected by AQ_ENV=staging

    class server(BaseEnv.server):
        host    = "0.0.0.0"
        workers = 2
        debug   = False

# ─── Production overrides ────────────────────────────────────────────────────
class ProdEnv(BaseEnv):
    env = "prod"                        # selected by AQ_ENV=prod

    class server(BaseEnv.server):
        host    = "0.0.0.0"
        workers = Env("WEB_WORKERS", default=4, cast=int)
        timeout_keep_alive        = 30
        timeout_graceful_shutdown = 30
        proxy_headers             = True
        forwarded_allow_ips       = "*"

    class auth(BaseEnv.auth):
        password_hasher = AquilaConfig.PasswordHasher.argon2id(
            time_cost=3, memory_cost=131072
        )

    class database(BaseEnv.database):
        pool_size   = 20
        auto_migrate = True

    class di(BaseEnv.di):
        scope_enforcement   = "raise"   # fail-fast on captive deps
        parallel_resolution = True      # resolve independent deps concurrently

# ─── Wire into Workspace ─────────────────────────────────────────────────────
workspace = (
    Workspace("myapp")
    .env_config(BaseEnv)                # reads AQ_ENV → selects DevEnv / ProdEnv
    .module(...)
)
```

```python
class server(AquilaConfig.Server):
    # ── Core ──────────────────────────────────────────────
    host    = "0.0.0.0"
    port    = Env("PORT", default=8000, cast=int)
    workers = Env("WEB_WORKERS", default=4, cast=int)
    uds     = None           # Unix domain socket path (alternative to host:port)
    fd      = None           # File descriptor to bind
    debug   = False
    mode    = "prod"

    # ── Hot reload (dev only) ─────────────────────────────
    reload          = False
    reload_dirs     = ["app/", "modules/"]
    reload_delay    = 0.25      # seconds between checks
    reload_includes = ["*.py"]  # glob patterns to include
    reload_excludes = ["*.pyc"] # glob patterns to exclude

    # ── Protocol ─────────────────────────────────────────
    http      = "auto"   # "auto" | "h11" | "httptools"
    ws        = "auto"   # "auto" | "wsproto" | "websockets" | "none"
    lifespan  = "auto"   # "auto" | "on" | "off"
    interface = "auto"   # "auto" | "asgi3" | "asgi2" | "wsgi"
    loop      = "auto"   # "auto" | "asyncio" | "uvloop"

    # ── Timeouts ─────────────────────────────────────────
    timeout_keep_alive        = 5    # seconds (HTTP keep-alive idle)
    timeout_graceful_shutdown = 30   # None = wait forever
    timeout_worker_healthcheck = 30  # seconds before worker is restarted

    # ── Limits ───────────────────────────────────────────
    backlog           = 2048
    limit_concurrency = None   # max concurrent connections
    limit_max_requests = None  # restart worker after N requests

    # ── Proxy / Headers ──────────────────────────────────
    proxy_headers       = True
    forwarded_allow_ips = "*"   # comma-separated or "*" (trust all)
    server_header       = True
    date_header         = True
    root_path           = ""    # ASGI root_path for reverse proxy

    # ── Logging ──────────────────────────────────────────
    access_log = True
    log_level  = "info"         # critical|error|warning|info|debug|trace
    use_colors = None           # None = auto-detect terminal

    # ── WebSocket ────────────────────────────────────────
    ws_max_size            = 16_777_216   # 16 MiB
    ws_max_queue           = 32
    ws_ping_interval       = 20.0         # seconds
    ws_ping_timeout        = 20.0         # seconds
    ws_per_message_deflate = True

    # ── TLS / SSL ────────────────────────────────────────
    ssl_certfile         = "/etc/certs/cert.pem"
    ssl_keyfile          = "/etc/certs/key.pem"
    ssl_keyfile_password = None
    ssl_ca_certs         = None
    ssl_ciphers          = "TLSv1"

    # ── HTTP/1.1 ─────────────────────────────────────────
    h11_max_incomplete_event_size = None  # bytes; None = h11 default (16 KiB)
```

```python
from aquilia.pyconfig import Env

class server(AquilaConfig.Server):
    # cast=int  → "8000" string becomes integer 8000
    port    = Env("PORT",        default=8000,        cast=int)
    workers = Env("WEB_WORKERS", default=4,           cast=int)

    # cast=bool → "true"/"yes"/"on"/"1" → True; "false"/"no"/"off"/"0" → False
    debug   = Env("AQ_DEBUG",    default=False,       cast=bool)

    # No cast — auto-casts: int → float → JSON → str
    host    = Env("AQ_HOST",     default="127.0.0.1")

    # required=True → raises ConfigMissingFault if unset and no default
    db_url  = Env("DATABASE_URL", required=True)

class auth(AquilaConfig.Auth):
    # Access via descriptor protocol: no .resolve() call needed
    access_token_ttl_minutes = Env("JWT_TTL_MINUTES", default=60, cast=int)

# ── Advanced: disable auto-load for explicit control ─────────────────────────
from aquilia.pyconfig import Env
Env.disable_auto_load()
from aquilia.dotenv import load_dotenv
load_dotenv(".env.custom")         # Load manually
Env.enable_auto_load()             # Re-enable for subsequent accesses
```



---

## .env Files
**URL**: `https://tubox.cloud/docs/config/dotenv`

.env Files aquilia.dotenv — zero-dependency, production-ready .env loader Aquilia ships its own DotEnv loader — no python-dotenv required. It loads .env files automatically before any Env or Secret binding is first resolved. It supports variable interpolation, multiline values, the export keyword, and escape sequences in double-quoted strings. Values already in the process environment are never overwritten by default — Docker, Kubernetes, and CI/CD injected secrets always win. , , ', sub: 'env-specific', color: '#f59e0b' }, .local', sub: 'local env-specific', color: '#3b82f6' }, , ].map(( , i) => ( ))} ← lower priority · · · · · · · · · · · · higher priority → Quick start In most apps you never call load_dotenv() at all — loading fires automatically the first time any Env or Secret descriptor is resolved. If you need explicit control: Complete syntax reference Aquilia's parser is a strict, safe subset of the de-facto .env standard. No shell expansion, no subshells, no eval(). File precedence and environment cascade Aquilia searches for files in this exact order, resolved from the workspace root (the directory containing workspace.py). Later files override earlier ones. os.environ always wins regardless of override — that flag only controls whether dotenv values overwrite other dotenv-sourced values. File Priority Commit? Purpose ', '3', 'Usually yes', 'Environment-specific values (.env.dev, .env.staging, .env.prod). Non-sensitive settings committed here.'], ['.env. .local', '4 — Highest', 'No — gitignore', 'Local per-environment overrides for developer machines. Never committed.'], ['config/.env', 'Parallel', 'Yes', 'Alternative location under config/ — same rules as .env.'], ['config/.env. ', 'Parallel', 'Usually yes', 'Alternative location for env-specific config under config/.'], ['os.environ (process)', 'Always wins', '—', 'CI/CD, Docker, Kubernetes. Never overwritten by .env files (override=False default).'], ['.env.example', 'Never loaded', 'Yes', 'Template checked into VCS for onboarding. Not a config source — copy to .env to use.'], ].map(([file, priority, commit, purpose], i) => ( ))} Add .env.local and .env.*.local to your .gitignore. These files are for machine-specific secrets and should never reach version control. Workspace root discovery Before loading any file, Aquilia resolves the workspace root directory. The search order is: AQUILIA_WORKSPACE environment variable — if set, used directly as the root path. Current working directory (cwd) — if it contains workspace.py. Walk up the directory tree — up to 10 levels, checking each parent for workspace.py. Fall back to cwd if no workspace.py is found anywhere. The environment mode used for '} substitution in file paths is resolved from AQUILIA_ENV → AQ_ENV → "dev". The value "production" is normalised to "prod" automatically. DotEnv class — parse and load The DotEnv class exposes two independent operations: parse (reads file → returns dict, no side effects) and load (reads file → writes to os.environ). Use parse when you need to inspect values without affecting the running process. DotEnvLoader — singleton for automatic loading DotEnvLoader is the framework's internal singleton that ensures .env files are loaded exactly once, thread-safely, regardless of how many concurrent requests access Env descriptors simultaneously. It uses a threading.Lock to protect the loaded-once state. Class method Returns Description ))} Module-level functions These are convenience wrappers around DotEnv and DotEnvLoader for the most common use cases. Import them directly from aquilia.dotenv. Function Returns Description ))} AquilaConfig.Dotenv — fine-grained policy For full control over which files are loaded and in what order, define a nested Dotenv class inside your AquilaConfig subclass. This is the declarative approach and the one that works best with IDE autocompletion. Variable interpolation Interpolation expands '} and $VAR references inside values. The resolution order within a single file is: already-resolved keys from earlier lines → later keys in the same file → os.environ. This means forward references don't resolve — order matters. Security guarantees — ))} Recommended .gitignore entries Typical project layout REDIS_URL=redis://localhost:6379/0`} /> Testing with .env files Reset loader state between tests using the autouse fixture pattern. Because DotEnvLoader.reset() does not remove values from os.environ, you also need monkeypatch to fully isolate environment variable state. ))} )

### Code Examples
```python
from aquilia.dotenv import load_dotenv, DotEnv, is_dotenv_loaded

# ── Auto-load (idempotent — always safe to call multiple times) ───────────────
load_dotenv()                            # searches workspace root for .env

# ── Load a specific file ──────────────────────────────────────────────────────
load_dotenv(".env.production")           # returns True if any values were loaded

# ── Load with override (replace existing os.environ values) ──────────────────
load_dotenv(override=True)               # use only in tests

# ── Parse WITHOUT loading into os.environ ────────────────────────────────────
values: dict[str, str] = DotEnv.parse(".env")
print(values["DATABASE_URL"])            # reads the file, returns dict, no side effects

# ── Parse from a raw string ───────────────────────────────────────────────────
values = DotEnv.parse_string("HOST=localhost\nPORT=8000")

# ── Check if already loaded ───────────────────────────────────────────────────
if not is_dotenv_loaded():
    load_dotenv()
```

```python
# ── Comments ─────────────────────────────────────────────────────────────
# Lines starting with # are ignored

# ── Simple assignments ────────────────────────────────────────────────────
SIMPLE=value                             # unquoted — inline # starts a comment
QUOTED="value with spaces"              # double-quoted — escape sequences processed
SINGLE='literal value'                   # single-quoted — no escape processing

# ── The export keyword is accepted and silently stripped ─────────────────
export EXPOSED=something                 # same as EXPOSED=something
EXPORT=also valid                        # bare EXPORT=... also works

# ── Booleans (Env(cast=bool) understands all of these) ──────────────────
AQ_DEBUG=true                            # → True
AQ_DEBUG=false                           # → False
AQ_DEBUG=yes                             # → True
AQ_DEBUG=no                              # → False
AQ_DEBUG=on                              # → True
AQ_DEBUG=off                             # → False
AQ_DEBUG=1                               # → True
AQ_DEBUG=0                               # → False

# ── Auto-cast numbers (when no cast= on Env) ────────────────────────────
PORT=8000                                # → int 8000
RATIO=0.95                               # → float 0.95

# ── Variable interpolation ────────────────────────────────────────────────
# ${VAR} and $VAR are both supported. Lookup order:
#   already-resolved vars in this file → earlier lines → os.environ
BASE_URL=http://localhost:8000
API_URL=${BASE_URL}/api                  # → "http://localhost:8000/api"
ALT_URL=$BASE_URL/v2                     # → same without braces
ESCAPE_DOLLAR=$100                       # \$ is a literal dollar sign

# ── Escape sequences (double-quoted only) ────────────────────────────────
NEWLINES="line1\nline2\nline3"           # \\n → actual newline
TABS="col1\tcol2"                        # \\t → actual tab
ESCAPED_QUOTE="He said \"hello\""        # \\" → literal double-quote
ESCAPED_DOLLAR="Price: $50"             # \$ → literal dollar sign

# ── Multiline values (double or single quotes) ───────────────────────────
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3jGkVFKA...
-----END RSA PRIVATE KEY-----"

# ── Inline comments (unquoted values only) ───────────────────────────────
HOST=localhost    # this part is stripped
FULL="value # not a comment"            # inside quotes → literal #
```

```python
from aquilia.dotenv import find_dotenv

# find_dotenv() applies the same workspace-root search
path = find_dotenv()                       # → Path("/path/to/project/.env") or None
path = find_dotenv(".env.staging")         # find a specific filename
path = find_dotenv(usecwd=True)            # restrict to current directory only
path = find_dotenv(raise_error=True)       # raise FileNotFoundError if not found
```



---

## AppManifest
**URL**: `https://tubox.cloud/docs/config/manifest`

import from 'lucide-react' AppManifest aquilia.manifest — per-module component registry & request-pipeline declaration Every module in Aquilia has an AppManifest — a dataclass that acts as the definitive component registry for that module. It declares which controllers, services, models, guards, pipes, interceptors, tasks, and middleware the module contributes. The Module in workspace.py is just a name pointer; the manifest.py inside the module directory is the source of truth. No import-time side effects, fully serialisable, inspectable, and fingerprint-stable. workspace.py Workspace("myapp") .module(Module("users")) .module(Module("auth")) .integrate(...) resolves modules/users/manifest.py AppManifest(name="users", ...) , , , , , , , , , ].map(( ) => ( ))} compiled Runtime Subsystems , , , , , , , ].map(( ) => ( ))} exports → imports cross-module DI workspace.py is the orchestrator — manifest.py is the source of truth — the runtime compiles manifests into live subsystems Minimal manifest Create modules/users/manifest.py. Every component is a dot-path string in the form "module.path:ClassName". The : separator is required — __post_init__ validates and raises ManifestInvalidFault if it is missing. Full field reference Field Type Description ))} ComponentRef — typed references with metadata When you need to attach metadata (priority, feature flags, custom config) to a component declaration, use ComponentRef instead of a bare string. The class_path must contain a : separator — ManifestInvalidFault is raised at construction if it does not. ComponentKind — classification enum Used in ComponentRef to classify the component for auto-discovery, filtering, and inspection. All values are lowercase strings. Kind Value Used for ))} ServiceScope — DI lifecycle Scope Lifetime Use for ))} Guards, Pipes, and Interceptors These three types form the v2 request pipeline. They are evaluated before the route handler runs, in order: guards first (gate), then pipes (transform), then interceptors (wrap). All are declared as dot-path strings or ComponentRef. LifecycleConfig — startup and shutdown hooks Hooks are declared as dot-path strings — not callables. This enables lazy loading, manifest serialisation, and fingerprinting without importing the actual function at manifest parse time. The runtime resolves and calls them in topological dependency order. BackgroundTaskConfig — task declarations Declares which @task-decorated functions this module contributes. Tasks listed here are auto-registered with the TaskManager during server startup. The @task decorator provides the runtime metadata (retry policy, queue, timeout); this config gives the manifest layer visibility into what tasks a module owns. Cross-module exports and imports Aquilia's DI system is module-scoped by default — one DI container per module, fully isolated. To share a service across module boundaries, export it from the provider and import the module name in the consumer. The framework resolves all exports into the consumer's DI container automatically at boot. FeatureConfig — conditional activation Feature flags control which services, controllers, middleware, and routes are registered at boot time. Useful for gradual rollouts, A/B testing, or environment-conditional features. auto_discover — convention over configuration When auto_discover=True (the default), Aquilia scans the following subdirectories inside the module package directory and auto-registers anything it finds that matches the expected base classes. Explicit declarations in the manifest take precedence over discovered components. Per-module API versioning Use AppVersioningConfig or the convenience versioning() function to override the workspace-level versioning strategy for a specific module. Fingerprinting — reproducible deploys Every manifest exposes a .fingerprint() method that produces a 16-character SHA-256 hash of the manifest's serialised to_dict() output. This enables reproducible deploy verification — if the fingerprint changes between deploys, you know the component registry changed. Deprecated fields These fields still work at runtime but emit DeprecationWarning via Python's warnings module. Migrate to the current alternatives before the next major release. Deprecated field Replacement What the runtime does ))} Full production manifest ))} )

### Code Examples
```python
# modules/users/manifest.py
from aquilia.manifest import AppManifest

manifest = AppManifest(
    name="users",           # must match Module("users") in workspace.py
    version="0.1.0",
    description="User management — CRUD, profiles, roles",
    author="Platform Team",

    controllers=["modules.users.controllers:UsersController"],
    services=["modules.users.services:UsersService"],
    models=["modules.users.models:User", "modules.users.models:Role"],

    # Exports make UsersService available to other modules that import "users"
    exports=["UsersService"],
)
```

```python
from aquilia.manifest import (
    AppManifest, ComponentRef, ComponentKind,
    ServiceConfig, ServiceScope, MiddlewareConfig,
)

manifest = AppManifest(
    name="auth",
    version="1.0.0",

    # ── Services with explicit DI scope and aliases ───────────────────────
    services=[
        # String shorthand (scope=APP by default)
        "modules.auth.services:AuthService",

        # Full ServiceConfig — explicit control
        ServiceConfig(
            class_path="modules.auth.services:TokenService",
            scope=ServiceScope.REQUEST,   # New instance per HTTP request
            aliases=["TokenProvider"],    # Alternative injection names
            tag="jwt",                    # For Inject(tag="jwt") resolution
            observable=True,             # Include in metrics/tracing
        ),

        # ServiceConfig with factory pattern
        ServiceConfig(
            class_path="modules.auth.services:OAuthClient",
            scope=ServiceScope.SINGLETON,
            factory="modules.auth.factories:make_oauth_client",
            factory_args={"timeout": 30},
        ),
    ],

    # ── Guards via ComponentRef ───────────────────────────────────────────
    guards=[
        ComponentRef(
            "modules.auth.guards:JWTGuard",
            ComponentKind.GUARD,
            metadata={"priority": 10},      # lower = evaluated first
        ),
        ComponentRef(
            "modules.auth.guards:RoleGuard",
            ComponentKind.GUARD,
            metadata={"priority": 20},
        ),
    ],

    # ── Middleware with priority ──────────────────────────────────────────
    middleware=[
        MiddlewareConfig(
            class_path="modules.auth.middleware:AuditMiddleware",
            scope="global",        # "global" | "app" | "route"
            priority=30,           # lower = earlier in pipeline
            log_requests=True,
        ),
    ],
)
```

```python
from aquilia.manifest import AppManifest, ComponentRef, ComponentKind, MiddlewareConfig

manifest = AppManifest(
    name="api",
    version="1.0.0",

    # ── Guards: authentication / authorisation gates ──────────────────────
    # Evaluated before the route handler. Return False or raise to block.
    guards=[
        "modules.api.guards:JWTGuard",          # validates JWT, populates request.user
        "modules.api.guards:PermissionGuard",    # checks request.user has required permissions
        ComponentRef(
            "modules.api.guards:RateLimitGuard",
            ComponentKind.GUARD,
            metadata={"priority": 5},            # evaluated first (lower priority number)
        ),
    ],

    # ── Pipes: input transformation and validation ────────────────────────
    # Transform and coerce incoming request data before the handler sees it.
    pipes=[
        "modules.api.pipes:ValidationPipe",     # validate against Contract schema
        "modules.api.pipes:SanitizationPipe",   # strip HTML/XSS from string inputs
        "modules.api.pipes:ParseIntPipe",       # coerce string IDs to int
    ],

    # ── Interceptors: cross-cutting concerns ─────────────────────────────
    # Wrap handler execution — run code before AND after the response.
    interceptors=[
        "modules.api.interceptors:CacheInterceptor",     # read/write response cache
        "modules.api.interceptors:LoggingInterceptor",   # structured request logging
        "modules.api.interceptors:MetricsInterceptor",   # OpenTelemetry spans
    ],
)
```



---

## Request
**URL**: `https://tubox.cloud/docs/request-response`

Core Request The Request class is a performance-optimized, class-based HTTP request wrapper built directly on the ASGI scope. It leverages __slots__ for low memory overhead and features lazy, cached property accessors for headers, queries, cookies, and bodies. Request Lifecycle & Architecture The following low-level system design diagram illustrates how an incoming ASGI client payload traverses the lazy-evaluation and protection boundaries: ASGI Entry Raw Connection Scope Security Guards Max Body / ReDoS limit Lazy Parser Cache Headers/Cookies/Body Controller Engine RequestCtx Injection Architecture & Slots To eliminate dictionary overhead, Request uses Python's __slots__ mapping for all internal state fields. class Request: __slots__ = ( "scope", "_receive", "_send", "max_body_size", "max_field_count", "max_file_size", "upload_tempdir", "trust_proxy", "chunk_size", "json_max_size", "json_max_depth", "form_memory_threshold", "state", "_body", "_body_consumed", "_json", "_surp", "_form_data", "_query_params", "_headers", "_cookies", "_url", "_disconnected", "_temp_files", ) Request Faults Request validation and parsing failures trigger structured exceptions mapped to the Aquilia Fault system: Fault Class Fault Code HTTP Status Description , , , , , , , ].map((row, i) => ( ))} Constructor & Config The Request object is initialized with the ASGI scope, receive, and optional send callables: Request( scope: dict, # ASGI scope receive: Callable, # ASGI receive channel send: Callable | None = None, # ASGI send channel (optional) *, max_body_size: int = 10_485_760, # 10 MB body limit max_field_count: int = 1000, # Max form fields max_file_size: int = 2_147_483_648,# 2 GB uploaded file limit upload_tempdir: Path | None = None,# Path for temp files trust_proxy: bool | list[str] = False, # Blanket trust or trusted CIDRs list chunk_size: int = 65536, # Byte streaming chunk size json_max_size: int = 10_485_760, # 10 MB JSON size limit json_max_depth: int = 64, # Max JSON nest depth form_memory_threshold: int = 1048576, # 1 MB memory limit before spilling uploads to disk ) Core Properties & Accessors Attribute Type Description , , , , , , , , , ].map((row, i) => ( ))} Client IP & Proxy Trust The client_ip() method determines the client's IP. When trust_proxy is configured with a list of networks, it walks the X-Forwarded-For list from right to left, returning the rightmost IP that is not in the trusted set to prevent client spoofing. # Initialize with trusted proxy CIDRs req = Request(scope, receive, trust_proxy=["10.0.0.0/8", "192.168.1.0/24"]) # Client IP resolution ip = req.client_ip() Body Reading & Streaming Reading the body is idempotent and cached. If the body is read via await request.body(), subsequent calls return the cached bytes instantly. # Read full body (cached) body_bytes = await request.body() body_text = await request.text(encoding="utf-8") # Stream bytes in chunks async for chunk in request.iter_bytes(chunk_size=16384): await process_chunk(chunk) # Read exactly n bytes header = await request.readexactly(1024) Note: Calling iter_bytes() directly consumes the stream from ASGI. If you need to read the body both as a stream and as single-shot bytes, call await request.body() first to cache it. JSON & SURP Input Validation The json() and surp() methods parse the request body and support direct model validation: # Parse JSON as dict/list data = await request.json() # Parse and validate using a Pydantic model user = await request.json(model=UserCreateRequest) Auth, Session & DI Integration The Request coordinates with middleware to expose authenticated identity, active sessions, and dependency injection scopes: # Get active identity identity = request.identity is_auth = request.authenticated # Require auth (raises AUTH_REQUIRED structured fault if unauthenticated) user = request.require_identity() # Session integration session = request.session session["views"] = session.get("views", 0) + 1 # Dependency injection resolution db_service = await request.resolve(DatabaseService) Config Integrations Response )

### Code Examples
```python
class Request:
    __slots__ = (
        "scope",
        "_receive",
        "_send",
        "max_body_size",
        "max_field_count",
        "max_file_size",
        "upload_tempdir",
        "trust_proxy",
        "chunk_size",
        "json_max_size",
        "json_max_depth",
        "form_memory_threshold",
        "state",
        "_body",
        "_body_consumed",
        "_json",
        "_surp",
        "_form_data",
        "_query_params",
        "_headers",
        "_cookies",
        "_url",
        "_disconnected",
        "_temp_files",
    )
```

```python
Request(
    scope: dict,                       # ASGI scope
    receive: Callable,                 # ASGI receive channel
    send: Callable | None = None,      # ASGI send channel (optional)
    *,
    max_body_size: int = 10_485_760,   # 10 MB body limit
    max_field_count: int = 1000,        # Max form fields
    max_file_size: int = 2_147_483_648,# 2 GB uploaded file limit
    upload_tempdir: Path | None = None,# Path for temp files
    trust_proxy: bool | list[str] = False, # Blanket trust or trusted CIDRs list
    chunk_size: int = 65536,           # Byte streaming chunk size
    json_max_size: int = 10_485_760,   # 10 MB JSON size limit
    json_max_depth: int = 64,          # Max JSON nest depth
    form_memory_threshold: int = 1048576, # 1 MB memory limit before spilling uploads to disk
)
```

```python
# Initialize with trusted proxy CIDRs
req = Request(scope, receive, trust_proxy=["10.0.0.0/8", "192.168.1.0/24"])

# Client IP resolution
ip = req.client_ip()
```



---

## Response
**URL**: `https://tubox.cloud/docs/request-response/response`

Core Response The Response class is the core HTTP response builder for Aquilia, designed for performance-critical streaming and flexible serialization. It supports content negotiation, block compression (Gzip/Brotli), Range requests (HTTP 206), cookie signing, and background tasks. Response Transmission Pipeline The following low-level system design diagram illustrates how outbound data is negotiated, encoded, and dispatched to the ASGI channel: Handler Yield Dict / Model / Bytes Content Negotiation JSON / XML / SURP molding Compression / Range Gzip/Brotli/Range headers ASGI Send Background Tasks run Response Faults Fault Class Fault Code Description , , , , ].map((row, i) => ( ))} Constructor Response( content: Any = b"", # Response payload (bytes, str, list/dict, iterator) status: int = 200, # HTTP status code headers: Mapping | None = None, # Key-value response headers media_type: str | None = None, # Media type override *, background: BackgroundTask | None = None, # Task to run post-transmission encoding: str = "utf-8", # Text body encoding validate_headers: bool = True, # Guard against header injection ) Factory Methods Standard Formats # JSON (optimized using orjson/ujson automatically) Response.json( , status=200) # HTML Response.html(" Welcome ", status=200) # Plain Text Response.text("OK", status=200) # Redirect Response.redirect("/new-location", status=307) Binary & Content Negotiation (SURP) Aquilia supports the SURP binary format. Response.negotiated() automatically parses quality factors from the client's Accept header to choose between SURP and JSON: # Explicit SURP Response (falls back to JSON if surp is missing) Response.surp( , status=200, compression="lz4") # Content-negotiated Response Response.negotiated( , ctx.request) Streaming & SSE # Stream raw bytes from an async generator Response.stream(async_bytes_generator(), media_type="application/octet-stream") # Server-Sent Events (SSE) Response.sse(sse_event_generator()) HLS Media Streaming Aquilia provides native helpers to serve HLS playlists (.m3u8) and MPEG-TS media segments: from aquilia.response import HLSSegment, HLSVariant # Serve HLS Media Playlist Response.hls_playlist( segments=[ HLSSegment(uri="seg1.ts", duration=4.0), HLSSegment(uri="seg2.ts", duration=3.8) ], target_duration=4 ) # Serve HLS Master Playlist Response.hls_master_playlist( variants=[ HLSVariant(uri="low/index.m3u8", bandwidth=800000, resolution="480x270"), HLSVariant(uri="high/index.m3u8", bandwidth=2400000, resolution="1280x720") ] ) Cookie Management Cookies can be signed using CookieSigner to prevent client-side tampering. # Initialize signer with key signer = CookieSigner(secret_key="secure-random-key") response = Response.text("Hello") # Set signed cookie response.set_cookie( "session_id", "value", secure=True, httponly=True, samesite="Lax", signed=True, signer=signer ) # Delete cookie response.delete_cookie("session_id") Background Tasks Background tasks execute sequentially after the response bytes have been completely flushed to the client: from aquilia.response import CallableBackgroundTask async def send_welcome_email(): await email_service.send("Welcome!") response = Response.json( ) response._background_tasks.append( CallableBackgroundTask(send_welcome_email) ) Request Data Structures )

### Code Examples
```python
Response(
    content: Any = b"",                  # Response payload (bytes, str, list/dict, iterator)
    status: int = 200,                   # HTTP status code
    headers: Mapping | None = None,      # Key-value response headers
    media_type: str | None = None,       # Media type override
    *,
    background: BackgroundTask | None = None, # Task to run post-transmission
    encoding: str = "utf-8",             # Text body encoding
    validate_headers: bool = True,       # Guard against header injection
)
```

```python
# JSON (optimized using orjson/ujson automatically)
Response.json({"data": "value"}, status=200)

# HTML
Response.html("<h1>Welcome</h1>", status=200)

# Plain Text
Response.text("OK", status=200)

# Redirect
Response.redirect("/new-location", status=307)
```

```python
# Explicit SURP Response (falls back to JSON if surp is missing)
Response.surp({"nodes": [...]}, status=200, compression="lz4")

# Content-negotiated Response
Response.negotiated({"payload": data}, ctx.request)
```



---

## Data Structures
**URL**: `https://tubox.cloud/docs/request-response/data-structures`

Request / Data Structures Data Structures Aquilia provides performance-optimized, purpose-built data structures in aquilia._datastructures for request parsing: MultiDict for multi-value dictionaries, Headers for case-insensitive header access, and URL for immutable URL component parsing and manipulation. MultiDict A dictionary that supports multiple values per key. Implements MutableMapping. Used internally for query parameters and form data where keys can repeat (e.g. ?tag=python&tag=async). from aquilia._datastructures import MultiDict # Initialize from list of tuples params = MultiDict([ ("tag", "python"), ("tag", "async"), ("page", "1"), ]) # Standard dict access (returns FIRST value for key) params["tag"] # → "python" params.get("tag") # → "python" # Multi-value access params.get_all("tag") # → ["python", "async"] # Add values (doesn't replace) params.add("tag", "web") params.get_all("tag") # → ["python", "async", "web"] # Convert to plain dict (first value per key) params.to_dict() # → API Reference Method Returns Description , , , , ].map((row, i) => ( ))} Headers A case-insensitive header container built as a @dataclass. Eagerly processes and decodes raw header bytes from the ASGI scope while preserving original naming. from aquilia._datastructures import Headers headers = Headers(raw=[ (b"content-type", b"application/json"), (b"Authorization", b"Bearer abc123"), ]) # Case-insensitive lookup headers.get("Content-Type") # → "application/json" headers.has("authorization") # → True URL An immutable parsed URL component representation supporting modifications via copies. from aquilia._datastructures import URL url = URL.parse("https://api.example.com/users?page=2") url.host # → "api.example.com" url.path # → "/users" # Immutable replacement pattern url2 = url.replace(path="/articles") Response File Uploads )

### Code Examples
```python
from aquilia._datastructures import MultiDict

# Initialize from list of tuples
params = MultiDict([
    ("tag", "python"),
    ("tag", "async"),
    ("page", "1"),
])

# Standard dict access (returns FIRST value for key)
params["tag"]                  # → "python"
params.get("tag")              # → "python"

# Multi-value access
params.get_all("tag")          # → ["python", "async"]

# Add values (doesn't replace)
params.add("tag", "web")
params.get_all("tag")          # → ["python", "async", "web"]

# Convert to plain dict (first value per key)
params.to_dict()               # → {"tag": "python", "page": "1"}
```

```python
from aquilia._datastructures import Headers

headers = Headers(raw=[
    (b"content-type", b"application/json"),
    (b"Authorization", b"Bearer abc123"),
])

# Case-insensitive lookup
headers.get("Content-Type")  # → "application/json"
headers.has("authorization")  # → True
```

```python
from aquilia._datastructures import URL

url = URL.parse("https://api.example.com/users?page=2")
url.host    # → "api.example.com"
url.path    # → "/users"

# Immutable replacement pattern
url2 = url.replace(path="/articles")
```



---

## File Uploads
**URL**: `https://tubox.cloud/docs/request-response/uploads`

Request / File Uploads File Uploads Aquilia handles multipart file uploads natively via UploadFile and FormData objects, providing automatic disk-spilling and sanitization mechanisms to keep memory usage bounded. UploadFile Representing a single uploaded file. It operates in two modes: in-memory (for files smaller than the threshold) and on-disk (temporary files for large payloads). API Fields Field Type Description , , ].map((row, i) => ( ))} # Read file content (in-memory or streamed from disk) content: bytes = await upload.read() # Stream chunks (useful for large files to avoid memory overhead) async for chunk in upload.stream(): await process(chunk) # Save to destination path on disk saved_path = await upload.save("/dest/path/image.png", overwrite=True) FormData The parsed representation of form fields and files. Method Returns Description , , , ].map((row, i) => ( ))} Data Structures )

### Code Examples
```python
# Read file content (in-memory or streamed from disk)
content: bytes = await upload.read()

# Stream chunks (useful for large files to avoid memory overhead)
async for chunk in upload.stream():
    await process(chunk)

# Save to destination path on disk
saved_path = await upload.save("/dest/path/image.png", overwrite=True)
```



---

## Controllers
**URL**: `https://tubox.cloud/docs/controllers`

Controllers aquilia.controller — Class-based request handlers Controllers are the primary request handling abstraction in Aquilia. Unlike function-based routing, Aquilia controllers are classes that support dependency injection, lifecycle hooks, pipeline execution, rate limiting, and content negotiation. Low-Level System Design The following diagram details the low-level execution flow when a request matches a controller endpoint: 1. ASGI Router Matches CompiledRoute Route Compiler Bakes metadata 2. Factory (DI) Instantiates instance 3. Pipeline Nodes Guards / Interceptors 4. Param Binding Contract casting/seal 5. Execute Handler Invokes method The Controller Base Class All controllers extend Controller . The base class provides: Response: products = await self.repo.list_all() return Response.json( )`} /> Class Attributes Attribute Type Default Description ))} Instantiation Modes per_request (default) A new controller instance is created for each incoming request. It supports the async context manager protocol (__aenter__ / __aexit__) for request-level resources (e.g. transactions). singleton A single instance is shared across all requests and lives for the entire server lifespan. Stateful startup and shutdown lifecycle hooks are executed in this mode only. In This Section → Route Decorators: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, WS → RequestCtx: The request context object and its properties → ControllerFactory: How controllers are instantiated with DI )

### Code Examples
```python
from aquilia import Controller, GET, POST, PUT, DELETE, RequestCtx, Response

class ProductsController(Controller):
    # Class-level configuration
    prefix = "/api/products"
    pipeline = []
    tags = ["Products"]
    instantiation_mode = "per_request" # "per_request" or "singleton"

    # DI dependencies are injected into __init__
    def __init__(self, product_repo: ProductRepository):
        self.repo = product_repo

    # Route handler
    @GET("/")
    async def list_products(self, ctx: RequestCtx) -> Response:
        products = await self.repo.list_all()
        return Response.json({"products": products})
```



---

## Controller Attributes
**URL**: `https://tubox.cloud/docs/controllers/attributes`

Controller Attributes aquilia.controller.attrs — Declarative class-level metadata builder The Attributes class is a fluent, chainable builder used to configure class-level metadata on Controller subclasses. By leveraging Python's descriptor protocol, it guarantees compile-time validation and applies configurations dynamically at class-definition time with zero request-time runtime overhead. Old Style vs. New Style Deprecation Warning Directly overriding class attributes (e.g. prefix = "/users", pipeline = [...]) is now deprecated and scheduled for removal in future releases. All new controller definitions should use the modern Attributes builder assigned to the attr variable. Old Style (Deprecated) Overriding class-level variables directly: New Style (Recommended) Using the chainable Attributes descriptor: Why is the old style deprecated? Deferred Validation: Direct properties are not validated when the class is defined. Any misspelled attribute names or bad types will fail silently or crash later at runtime. Mutable State Leakage: Setting lists (like pipeline or tags) directly exposes them to default mutable value issues where subclasses might share or leak states. Poor Autocomplete Support: IDEs and linters cannot suggest options or provide typings for direct class variables. The fluent builder provides full IDE autocomplete. Design Philosophy & Performance Aquilia prioritizes performance, ensuring that request routing and context setup are as optimized as possible. The Attributes builder achieves this through three key architectural decisions: 1 __slots__ Optimization Using __slots__ eliminates the per-instance dictionary (__dict__). This reduces the memory footprint and speeds up attribute access in the method chain by approximately 40%. 2 __set_name__ Descriptor Protocol Rather than analyzing metadata on every request, the builder implements Python's __set_name__(self, owner, name). This executes exactly once when Python loads the controller class, applying the compiled metadata directly onto the controller type. 3 O(1) Chaining & Zero Allocations Each fluent method call does not clone or instantiate a new builder. Instead, it mutates the existing builder's slot field in O(1) time and returns self, generating zero trash collector allocations beyond list conversions for variadic args. Usage & Examples Assign the builder chain to a class-level variable named attr in any controller subclass. 1. Basic REST Configuration Configuring basic route grouping and OpenAPI tag classifications: Response: return Response.json( )`} /> 2. Advanced Enterprise Configuration Enforcing API versions, pipeline guards, rate limits, timeouts, and structured exception handlers at the class level: Response | None: ctx.state["logger_time"] = ctx.request_id return None async def after(self, ctx: RequestCtx, result: Response) -> Response: # Custom log post-processing return result class BillingController(Controller): attr = ( Attributes() .prefix("/api/billing") .tags("Finance", "Billing") .version(["v1", "v2"]) .instantiation_mode("singleton") .pipeline(JWTGuard) # Run auth guard for all routes .throttle(Throttle(limit=60, window=60)) # Rate limit: 60 req/min .interceptors(TransactionLogger()) # Attach request interceptor .exception_filters(DatabaseExceptionFilter()) # Catch DB exceptions .timeout(10.0) # Terminate route if execution > 10s .max_body_size(1024 * 1024) # Cap request payloads to 1MB ) @GET("/history") async def billing_history(self, ctx: RequestCtx) -> Response: return Response.json( )`} /> Fluent Builder API Reference The following list describes each chainable method exposed by the Attributes class: .prefix(value: str) -> Attributes Configures the base URL path prefix for all endpoints in the controller. Validation: The value must be a string and start with / or be empty (""). .pipeline(*nodes: Any) -> Attributes Accepts variadic positional arguments of guards, hooks, or middleware. They execute sequentially before the request hits the handler method. Validation: The arguments are collected as an iterable sequence. .tags(*tag_values: str) -> Attributes Specifies the OpenAPI documentation categories. All endpoints within the controller inherit these tags. Validation: Each tag item must be a valid string. .instantiation_mode(mode: Literal["per_request", "singleton"]) -> Attributes Controls the controller's lifecycle scope managed by the DI container. per_request: (Default) Instantiates a new controller instance per HTTP request. Supports request-scoped resources. singleton: Shares a single instance across all requests for the application's entire lifespans. Required for startup/shutdown hooks. .version(v: str | list[str]) -> Attributes Binds the controller endpoints to specific API versions (e.g. "v1"). Validation: Must be a string or a list of strings representing version names. .throttle(t: Throttle) -> Attributes Applies rate-limiting metrics at the class level via a Throttle instance. .interceptors(*items: Interceptor) -> Attributes Registers class-wide Interceptor hooks that intercept controller route processing before and after methods run. .exception_filters(*items: ExceptionFilter) -> Attributes Registers class-wide ExceptionFilter instances to convert raised exceptions to clean JSON payloads. .timeout(seconds: float) -> Attributes Sets the handler timeout in seconds. Requests running longer than this will yield a timeout fault. Validation: Must be a non-negative integer or float (>= 0). .max_body_size(bytes_size: int) -> Attributes Restricts request body payload sizes (in bytes) to prevent Denial of Service (DoS) attacks. Validation: Must be a non-negative integer (>= 0). Compile-Time Validation Aquilia prevents configuration errors from going unnoticed until runtime. The _validate engine is executed immediately during class evaluation (via __set_name__). If any parameters violate validation limits, Aquilia raises a ConfigInvalidFault during application startup. Definition-Time Error Surfacing By throwing during definition time, the server will refuse to start if paths are formatted incorrectly (e.g. prefix without /), or if limits are set below zero. This guarantees that route integrity does not depend on request test cases. Overview RequestCtx )

### Code Examples
```python
class ProductsController(Controller):
    prefix = "/api/products"
    tags = ["Products"]
    instantiation_mode = "singleton"
    timeout = 30.0
```

```python
class ProductsController(Controller):
    attr = (
        Attributes()
        .prefix("/api/products")
        .tags("Products")
        .instantiation_mode("singleton")
        .timeout(30.0)
    )
```

```python
from aquilia import Controller, GET, Attributes, RequestCtx, Response

class UsersController(Controller):
    # Configure path prefix and OpenAPI tags for all routes in this controller
    attr = (
        Attributes()
        .prefix("/api/users")
        .tags("Users", "Management")
    )

    @GET("/")
    async def get_all(self, ctx: RequestCtx) -> Response:
        return Response.json({"users": []})
```



---

## Route Decorators
**URL**: `https://tubox.cloud/docs/controllers/decorators`

Route Decorators aquilia.controller.decorators — HTTP method decorators Route decorators attach metadata to controller methods without import-time side effects. The metadata is later extracted by the ControllerCompiler to generate compiled routes, URL patterns, and OpenAPI specs. RouteDecorator Base All HTTP method decorators (GET, POST, etc.) inherit from RouteDecorator. The base class accepts the full set of parameters and stores them as a dict on func.__route_metadata__: Parameter Reference Parameter Type Description ))} HTTP Method Decorators Each HTTP method has a dedicated decorator class that sets self.method to the corresponding verb. All accept the same keyword arguments as RouteDecorator: Decorator HTTP Method Typical Use ))} Usage Examples Basic CRUD Response: """List all articles.""" return Response.json( ) @GET("/«id:int»") async def detail(self, ctx: RequestCtx, id: int) -> Response: """Get article by ID.""" return Response.json( ) @POST("/", status_code=201) async def create(self, ctx: RequestCtx) -> Response: """Create a new article.""" data = await ctx.json() return Response.json(data, status=201) @PUT("/«id:int»") async def replace(self, ctx: RequestCtx, id: int) -> Response: """Full replacement of an article.""" data = await ctx.json() return Response.json( ) @PATCH("/«id:int»") async def update(self, ctx: RequestCtx, id: int) -> Response: """Partial update of an article.""" data = await ctx.json() return Response.json( ) @DELETE("/«id:int»", status_code=204) async def delete(self, ctx: RequestCtx, id: int) -> Response: """Delete an article.""" return Response("", status=204)`} language="python" /> With Contracts Response: # body is the validated payload dictionary article = await self.repo.create(body) return Response.json(article, status=201) @PUT( "/«id:int»", request_contract=ArticleContract, response_contract=ArticleContract, ) async def update(self, ctx: RequestCtx, id: int, body: dict) -> Response: article = await self.repo.update(id, body) return Response.json(article)`} language="python" /> With Filtering and Pagination Response: """ List products with filtering, search, and pagination. Query params: ?category=electronics — exact match filter ?search=laptop — text search in name/description ?ordering=-price — sort by price descending ?page=2&page_size=20 — pagination """ products = await self.repo.list_all() # Filtering, ordering, and pagination are applied # automatically by the engine before the response is sent. return products`} language="python" /> Generic route() Function For multi-method routes or dynamic method binding, use the route() function instead of individual decorators: Response: return Response.json( ) @route(["GET", "POST"], "/bulk") async def bulk(self, ctx: RequestCtx) -> Response: """Handles both GET and POST on /items/bulk.""" if ctx.method == "GET": return Response.json( ) data = await ctx.json() return Response.json( , status=201) @route("PUT", "/«id:int»", tags=["Admin"], deprecated=True) async def legacy_update(self, ctx: RequestCtx, id: int) -> Response: return Response.json( )`} language="python" /> When a list of methods is provided, route() applies the corresponding decorator class for each method. This means the handler gets multiple entries in __route_metadata__, one per method. How Metadata Works When a decorator like @GET("/users") is applied, it doesn't execute any routing logic. Instead, it attaches a metadata dict to the function: , "request_serializer": None, "response_serializer": None, "request_contract": None, "response_contract": None, "filterset_class": None, "filterset_fields": None, "search_fields": None, "ordering_fields": None, "pagination_class": None, "renderer_classes": None, } ]`} language="python" /> The __route_metadata__ list supports multiple entries — this is how a single method can handle multiple HTTP methods via route(). The ControllerCompiler iterates this list during aq compile to generate CompiledRoute objects. Path Parameter Syntax Aquilia uses the «name:type» chevron syntax for path parameters, compiled by the aquilia.patterns system: WebSocket Decorator The @WS decorator marks a method as a WebSocket handler. The handler receives a WebSocket connection instead of returning an HTTP response: None: ws = ctx.request.websocket await ws.accept() try: while True: data = await ws.receive_json() await ws.send_json( ) except Exception: await ws.close()`} language="python" /> ← Controller Overview RequestCtx → )

### Code Examples
```python
class RouteDecorator:
    def __init__(
        self,
        path: Optional[str] = None,
        *,
        # ── Pipeline & Middleware ─────────────────────────────────
        pipeline: Optional[List[Any]] = None,

        # ── OpenAPI Documentation ─────────────────────────────────
        summary: Optional[str] = None,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None,
        deprecated: bool = False,
        response_model: Optional[type] = None,
        status_code: int = 200,

        # ── Contract Casting / Sealing ───────────────────────────
        request_contract: Optional[type] = None,
        response_contract: Optional[type] = None,

        # ── Filtering, Search, Ordering ───────────────────────────
        filterset_class: Optional[type] = None,
        filterset_fields: Optional[Union[List[str], Any]] = None,
        search_fields: Optional[List[str]] = None,
        ordering_fields: Optional[List[str]] = None,

        # ── Pagination ────────────────────────────────────────────
        pagination_class: Optional[type] = None,

        # ── Content Negotiation ───────────────────────────────────
        renderer_classes: Optional[List[Any]] = None,
    ): ...
```

```python
from aquilia import Controller, GET, POST, PUT, PATCH, DELETE, RequestCtx, Response

class ArticlesController(Controller):
    prefix = "/api/articles"
    tags = ["Articles"]

    @GET("/")
    async def list(self, ctx: RequestCtx) -> Response:
        """List all articles."""
        return Response.json({"articles": []})

    @GET("/«id:int»")
    async def detail(self, ctx: RequestCtx, id: int) -> Response:
        """Get article by ID."""
        return Response.json({"id": id})

    @POST("/", status_code=201)
    async def create(self, ctx: RequestCtx) -> Response:
        """Create a new article."""
        data = await ctx.json()
        return Response.json(data, status=201)

    @PUT("/«id:int»")
    async def replace(self, ctx: RequestCtx, id: int) -> Response:
        """Full replacement of an article."""
        data = await ctx.json()
        return Response.json({"id": id, **data})

    @PATCH("/«id:int»")
    async def update(self, ctx: RequestCtx, id: int) -> Response:
        """Partial update of an article."""
        data = await ctx.json()
        return Response.json({"id": id, **data})

    @DELETE("/«id:int»", status_code=204)
    async def delete(self, ctx: RequestCtx, id: int) -> Response:
        """Delete an article."""
        return Response("", status=204)
```

```python
from aquilia import Controller, GET, POST, PUT, RequestCtx, Response
from aquilia.contracts import Contract, Field

class ArticleContract(Contract):
    title: str = Field(max_length=200)
    body: str
    category_id: int

class ArticlesController(Controller):
    prefix = "/api/articles"

    @POST(
        "/",
        status_code=201,
        request_contract=ArticleContract,   # Auto-validates request body
        response_contract=ArticleContract,   # Auto-molds response
    )
    async def create(self, ctx: RequestCtx, body: dict) -> Response:
        # body is the validated payload dictionary
        article = await self.repo.create(body)
        return Response.json(article, status=201)

    @PUT(
        "/«id:int»",
        request_contract=ArticleContract,
        response_contract=ArticleContract,
    )
    async def update(self, ctx: RequestCtx, id: int, body: dict) -> Response:
        article = await self.repo.update(id, body)
        return Response.json(article)
```



---

## @GET
**URL**: `https://tubox.cloud/docs/controllers/decorators/get`

Back to Decorators @GET The @GET decorator handles HTTP GET requests. It is the workhorse for retrieving resources and listing collections, with built-in support for filtering, searching, sorting, and pagination. Basic Usage Response: """List all users.""" users = await self.repo.all() return Response.json(users) @GET("/«id:int»") async def get_user(self, ctx: RequestCtx, id: int) -> Response: """Get a single user by ID.""" user = await self.repo.get(id) return Response.json(user)`} language="python" /> Advanced Filtering Aquilia's @GET decorator integrates directly with the FilterSet system. You can enable declarative filtering without writing any boilerplate query parsing logic. 1. Simple Field Filtering Use filterset_fields to allow exact matching on specific fields. 2. Custom FilterSets For complex logic (ranges, multiple values, related fields), define a FilterSet class. Search & Ordering Full-Text Search Enable the ?search= query parameter by defining searchable fields. Dynamic Ordering Allow clients to sort results using ?ordering=field (or -field for descending). Pagination Pagination is handled by the pagination_class argument. The framework provides standard implementations, but you can also supply your own. Complete API Reference Argument Type Description path str URL path pattern (e.g., /users/«id:int»). Defaults to method name if None. filterset_fields list[str] List of fields to enable simple exact-match filtering on. search_fields list[str] Fields to search against when the search query param is present. ordering_fields list[str] Fields allowed in the ordering query param. pagination_class Type[Pagination] Class to handle pagination logic (PageNumber, LimitOffset, Cursor). renderer_classes list[Type[Renderer]] Renderers to use for Content-Type negotiation. )

### Code Examples
```python
from aquilia import Controller, GET, RequestCtx, Response

class UsersController(Controller):
    prefix = "/users"

    @GET("/")
    async def list_users(self, ctx: RequestCtx) -> Response:
        """List all users."""
        users = await self.repo.all()
        return Response.json(users)

    @GET("/«id:int»")
    async def get_user(self, ctx: RequestCtx, id: int) -> Response:
        """Get a single user by ID."""
        user = await self.repo.get(id)
        return Response.json(user)
```

```python
@GET("/", filterset_fields=["status", "role"])
# Enable ?status=active&role=admin automatically
```

```python
class ProductFilter(FilterSet):
    min_price = NumberFilter(field_name="price", lookup_expr="gte")
    max_price = NumberFilter(field_name="price", lookup_expr="lte")
    category = CharFilter(lookup_expr="iexact")

class ProductController(Controller):
    @GET("/", filterset_class=ProductFilter)
    async def list_products(self, ctx: RequestCtx):
        # Filters are applied automatically to the queryset in ctx
        ...
```



---

## @POST
**URL**: `https://tubox.cloud/docs/controllers/decorators/post`

Back to Decorators @POST The @POST decorator handles HTTP POST requests, typically used for creating resources. It provides robust mechanisms for request body validation via Contracts and response formatting. Basic Usage Input Validation & Serialization Aquilia utilizes Contracts to handle request body validation and enforce typed contracts. Response Formatting Control how your data is sent back to the client using response_contract. Key Parameters response_contract: Automatically serializes/molds the return value of the handler using a Contract schema. response_model: Used primarily for OpenAPI documentation to describe the success response schema. status_code: Sets the default HTTP status code (default: 200, typically 201 for POST). API Reference Argument Type Description request_contract Type[Contract] Contract for strictly typed request bodies. response_contract Type[Contract] Contract to mold outgoing response data. status_code int Default HTTP status code (e.g., 201). Previous: @GET Next: @PUT )

### Code Examples
```python
from aquilia import Controller, POST, RequestCtx, Response
 
class UsersController(Controller):
    prefix = "/users"
 
    @POST("/", status_code=201)
    async def create_user(self, ctx: RequestCtx):
        data = await ctx.json()
        user = await self.service.create(data)
        return Response.json(user, status=201)
```

```python
from aquilia.contracts import Contract, Field

class UserCreateContract(Contract):
    username: str = Field(max_length=50)
    email: str

# In your controller:
@POST("/", request_contract=UserCreateContract)
async def create(self, ctx: RequestCtx, body: dict):
    # body is fully validated and cast according to the contract schema
    user = await self.service.create(body)
    return Response.json(user)
```

```python
@POST(
    "/",
    status_code=201,
    response_contract=UserContract
)
async def create(self, ctx: RequestCtx, body: dict):
    user = await self.repo.create(body)
    # The return value will be auto-molded via UserContract
    return user
```



---

## @PUT
**URL**: `https://tubox.cloud/docs/controllers/decorators/put`

Back to Decorators @PUT The @PUT decorator handles HTTP PUT requests for full resource replacement. It enforces idempotency, meaning multiple identical requests should have the same effect as a single one. Basic Usage Replacement Semantics Unlike @PATCH, @PUT expects a complete representation of the resource. Accessing ctx.contract or using request_contract will typically enforce that all required fields are present. Validation Behavior When using request_contract with PUT, partial updates (missing required fields) will strictly fail validation. Use @PATCH if you want to allow partial data. Previous: @POST Next: @PATCH )

### Code Examples
```python
from aquilia import Controller, PUT, RequestCtx, Response
 
class UsersController(Controller):
    prefix = "/users"
 
    @PUT("/«id:int»")
    async def update_user(self, ctx: RequestCtx, id: int):
        """Fully replace the user resource."""
        data = await ctx.json()
        user = await self.service.replace(id, data)
        return Response.json(user)
```

```python
@PUT(
    "/«id:int»",
    request_contract=UserContract,  # Strict: Requires all fields
    response_contract=UserContract
)
async def update(self, ctx: RequestCtx, id: int, body: dict):
    user = await self.repo.update(id, body)
    return Response.json(user)
```



---

## @PATCH
**URL**: `https://tubox.cloud/docs/controllers/decorators/patch`

Back to Decorators @PATCH The @PATCH decorator handles HTTP PATCH requests, used for partial modifications of a resource. Clients only need to send the fields they wish to change. Basic Usage Partial Updates with Contracts In Aquilia, partial updates are modeled using optional fields in a Contract or by utilizing projected references to validate a subset of fields. Schema Tip For partial PATCH operations, define the fields in your update contract as optional (e.g. using Field(required=False) or having a default value). Previous: @PUT Next: @DELETE )

### Code Examples
```python
from aquilia import Controller, PATCH, RequestCtx, Response, exceptions
 
class UsersController(Controller):
    prefix = "/users"
 
    @PATCH("/«id:int»")
    async def partial_update(self, ctx: RequestCtx, id: int):
        user = await self.repo.get_or_404(id)
        
        # Merge changes from request body
        payload = await ctx.json()
        updated_user = await self.repo.update(user, payload)
        
        return Response.json(updated_user)
```

```python
@PATCH(
    "/«id:int»",
    request_contract=UserUpdateContract,
    response_contract=UserContract
)
async def update(self, ctx: RequestCtx, id: int, body: dict):
    user = await self.repo.patch(id, body)
    return Response.json(user)
```



---

## @DELETE
**URL**: `https://tubox.cloud/docs/controllers/decorators/delete`

Back to Decorators @DELETE The @DELETE decorator handles HTTP DELETE requests, used to remove resources. Successful operations typically return an empty body with a 204 No Content status code. Basic Usage Response Semantics A DELETE operation is typically idempotent. If the resource is already gone, repeated calls should explicitly or implicitly succeed. 204 No Content The standard response for success. The client should not expect any content in the body. 202 Accepted Use this if the deletion is queued for background processing (soft delete, heavy cleanup). Warning: Body Content While HTTP specific allows a body in DELETE requests, many clients, proxies, and caches discard it. Avoid relying on request bodies for DELETE operations; use path parameters or query strings instead. Previous: @PATCH Next: @HEAD )

### Code Examples
```python
from aquilia import Controller, DELETE, RequestCtx, Response

class UsersController(Controller):
    prefix = "/users"

    @DELETE("/«id:int»")
    async def delete_user(self, ctx: RequestCtx, id: int):
        """Delete a user by ID."""
        success = await self.service.delete(id)
        if not success:
            return Response.status(404)
        
        # Return 204 No Content for successful deletion
        return Response.status(204)
```



---

## @HEAD
**URL**: `https://tubox.cloud/docs/controllers/decorators/head`

Back to Decorators @HEAD The @HEAD decorator handles HTTP HEAD requests, which are identical to GET requests except that the server must not return a message body. It is useful for efficient checks on resource existence, size, or modification time. Basic Usage Why use HEAD? Etag & Caching Clients can check if their cached version is still valid using If-None-Match headers against the Etag returned by HEAD. Large Resources Determine the download size (Content-Length) of a large file before committing to download it. Previous: @DELETE Next: @OPTIONS )

### Code Examples
```python
from aquilia import Controller, HEAD, GET, RequestCtx, Response

class FileController(Controller):
    
    @GET("/files/«filename»")
    async def download(self, ctx: RequestCtx, filename: str):
        file = await self.storage.get(filename)
        return Response.file(file)

    @HEAD("/files/«filename»")
    async def check_file(self, ctx: RequestCtx, filename: str):
        """Check file metadata without downloading."""
        meta = await self.storage.get_metadata(filename)
        if not meta:
            return Response.status(404)
        
        return Response(
            status=200,
            headers={
                "Content-Length": str(meta.size),
                "Last-Modified": meta.last_modified.isoformat(),
                "Content-Type": meta.content_type
            }
        )
```



---

## @OPTIONS
**URL**: `https://tubox.cloud/docs/controllers/decorators/options`

Back to Decorators @OPTIONS The @OPTIONS decorator handles HTTP OPTIONS requests, primarily used for Cross-Origin Resource Sharing (CORS) preflight checks and discovering allowed methods on a resource. Implicit vs Explicit Automatic Handling Aquilia's router automatically handles OPTIONS requests for CORS preflight if you have the CORS Middleware enabled. You rarely need to define @OPTIONS handlers manually. Manual Definition If you need custom logic for an OPTIONS request (e.g., dynamic capability advertising), you can define it explicitly. CORS Preflight Browsers send an OPTIONS request before making complex cross-origin requests (e.g., checks for headers like Authorization or Content-Type: application/json). The manual handler allows you to inspect Access-Control-Request-Method and Access-Control-Request-Headers to implement fine-grained security policies beyond global middleware settings. Previous: @HEAD Next: @WS )

### Code Examples
```python
from aquilia import Controller, OPTIONS, RequestCtx, Response

class ApiController(Controller):
    
    @OPTIONS("/")
    async def options(self, ctx: RequestCtx):
        return Response(
            status=204,
            headers={
                "Allow": "GET, POST, OPTIONS",
                "X-Api-Version": "2.0",
                "Access-Control-Allow-Methods": "GET, POST, OPTIONS"
            }
        )
```



---

## @WS
**URL**: `https://tubox.cloud/docs/controllers/decorators/ws`

Back to Decorators @WS The @WS decorator creates WebSocket endpoints for real-time, bidirectional communication. Unlike HTTP handlers, WebSocket handlers maintain a persistent connection. Basic Usage Connection Lifecycle A WebSocket handler has a distinct lifecycle compared to HTTP handlers. 1. Handshake The connection starts as an HTTP Upgrade request. Aquilia routes this to your handler. You must call await ws.accept() to complete the handshake, or the connection will close. 2. Message Loop Typically implemented as a while True loop. Use receive_text(), receive_bytes(), or receive_json() to wait for messages. 3. Disconnection When the client disconnects, `receive_*` methods will raise a `WebSocketDisconnect` exception. It is best practice to wrap your loop in a try/except block to handle cleanups. Differences from HTTP No Response Object: You do not return a `Response` object. You send data directly via `ws.send_*`. Middleware Limitations: Some global middleware (like GZip or Content-Length helpers) may not apply to the WebSocket stream itself, only the initial handshake. Pipelines: Route pipelines (`pipeline=[...]`) do not apply to WebSockets in the same way, as there isn't a single request/response cycle. However, guards run before the handler is invoked, allowing you to reject the handshake (e.g., authentication). Previous: @OPTIONS Next: @route )

### Code Examples
```python
from aquilia import Controller, WS, RequestCtx, WebSocket

class ChatController(Controller):
    
    @WS("/chat/«room_id»")
    async def chat_endpoint(self, ctx: RequestCtx, room_id: str):
        ws: WebSocket = ctx.websocket
        await ws.accept()
        
        try:
            while True:
                data = await ws.receive_text()
                await ws.send_text(f"Echo from {room_id}: {data}")
        except Exception:
            print("Client disconnected")
```



---

## @route
**URL**: `https://tubox.cloud/docs/controllers/decorators/route`

Back to Decorators @route The @route decorator acts as a generic factory that can apply multiple HTTP methods to a single handler function. It is useful for unifying logic or handling methods dynamically. Basic Usage Method Multiplexing Under the hood, @route iterates over the provided list of methods and applies the corresponding specific decorator (e.g., GET, POST) sequentially. Stacking Behavior Calling @route(["GET", "POST"]) is functionally equivalent to stacking: @GET(...) @POST(...) def handler(...): ... Previous: @WS Next: RequestCtx )

### Code Examples
```python
from aquilia import Controller, route, RequestCtx, Response

class GeneralController(Controller):
    
    # Handle both GET and POST on the same endpoint
    @route(["GET", "POST"], "/submit")
    async def handle_submit(self, ctx: RequestCtx):
        if ctx.method == "GET":
            return Response.html("Form HTML...")
        
        # POST logic
        data = await ctx.json()
        return Response.json({"received": data})
```



---

## RequestCtx
**URL**: `https://tubox.cloud/docs/controllers/request-ctx`

RequestCtx aquilia.controller.base.RequestCtx — Request context object The RequestCtx class encapsulates the request lifecycle, providing access to the current request, user identity, session state, DI container, and mutable state dict. Class Definition & slots For maximum performance, RequestCtx is optimized using Python __slots__, yielding up to 40% faster attribute access: Escape Hatch: If middleware or extensions need to set dynamic attributes, RequestCtx intercepts those calls via custom __getattr__ and __setattr__ methods, storing them inside the _extra dictionary safely. RequestCtx Object Pool To avoid heap allocation overhead during high-concurrency requests, Aquilia uses a lock-free _RequestCtxPool. Used internally by the engine to acquire and release contexts, resetting fields in-place: Delegated Properties & Methods For convenience, RequestCtx exposes properties that forward directly to the underlying Request object: Attribute Type Description ))} Route Decorators ControllerFactory )

### Code Examples
```python
class RequestCtx:
    __slots__ = (
        "request",
        "identity",
        "session",
        "auth",
        "container",
        "state",
        "request_id",
        "_extra",
    )

    def __init__(
        self,
        request: "Request",
        identity: Optional["Identity"] = None,
        session: Optional["Session"] = None,
        auth: Any | None = None,
        container: Any | None = None,
        state: dict[str, Any] | None = None,
        request_id: str | None = None,
    ):
        self.request = request
        self.identity = identity
        self.session = session
        self.auth = auth
        self.container = container
        self.state: dict[str, Any] = state if state is not None else {}
        self.request_id = request_id
        self._extra: dict[str, Any] | None = None
```

```python
# Behind the scenes:
ctx = _ctx_pool.acquire(request=request, container=container)
# ... execution ...
_ctx_pool.release(ctx)  # clears references to prevent GC leaks
```



---

## ControllerFactory
**URL**: `https://tubox.cloud/docs/controllers/factory`

ControllerFactory aquilia.controller.factory — DI-powered controller instantiation The ControllerFactory creates controller instances with full dependency injection support. It resolves constructor parameters and enforces singleton vs per-request scoping. InstantiationMode Enum ControllerFactory Class Attribute Type Description ))} DI Resolution Pipeline , , ].map(( ) => ( ))} RequestCtx ControllerEngine )

### Code Examples
```python
class InstantiationMode(str, Enum):
    PER_REQUEST = "per_request"  # New instance per HTTP request
    SINGLETON = "singleton"     # Single shared instance
```

```python
class ControllerFactory:
    # Class-level caches for constructor analysis
    _ctor_info_cache: Dict[Type, Any] = {}

    def __init__(self, app_container: Optional[Any] = None):
        self.app_container = app_container
        self._singletons: Dict[Type, Any] = {}
        self._startup_called: set = set()
```



---

## ControllerEngine
**URL**: `https://tubox.cloud/docs/controllers/engine`

ControllerEngine aquilia.controller.engine — Route dispatch and execution The ControllerEngine orchestrates the route execution pipeline. It coordinates dependency injection, clearance evaluations, pipeline middleware flow execution, parameter binding, response contract casting/molding, and content negotiation. Class Definition param names _has_lifecycle_hooks: Dict[type, tuple] = # class -> (has_on_request, has_on_response) _simple_route_cache: Dict[int, bool] = # id(route) -> is_simple _clearance_cache: Dict[int, Any] = # id(route) -> merged Clearance or None def __init__( self, factory: ControllerFactory, enable_lifecycle: bool = True, fault_engine: Optional[Any] = None, effect_registry: Optional[Any] = None, clearance_engine: Optional[Any] = None, ): self.factory = factory self.enable_lifecycle = enable_lifecycle self.fault_engine = fault_engine self.effect_registry = effect_registry self.clearance_engine = clearance_engine`} language="python" /> execute() — The Main Entry Point The execute() method is the entrypoint called by ASGI adapters to run a matched route: Response:`} language="python" /> , , , , , , , ].map(( ) => ( ))} Parameter Binding & Contract Context The engine binds path parameters, query parameters, body parameters, and dependencies automatically. If a parameter is typed as a Contract subclass, the engine parses the body and validates it: During contract validation, the engine creates a ContractContext wrapping the request container. This context provides lazy resolution via LazyServiceProxy, allowing contracts to access DI services asynchronously: ControllerFactory ControllerCompiler )

### Code Examples
```python
class ControllerEngine:
    # Class-level caches shared across instances
    _signature_cache: Dict[Any, inspect.Signature] = {}
    _pipeline_param_cache: Dict[int, set] = {}  # id(callable) -> param names
    _has_lifecycle_hooks: Dict[type, tuple] = {} # class -> (has_on_request, has_on_response)
    _simple_route_cache: Dict[int, bool] = {}    # id(route) -> is_simple
    _clearance_cache: Dict[int, Any] = {}        # id(route) -> merged Clearance or None

    def __init__(
        self,
        factory: ControllerFactory,
        enable_lifecycle: bool = True,
        fault_engine: Optional[Any] = None,
        effect_registry: Optional[Any] = None,
        clearance_engine: Optional[Any] = None,
    ):
        self.factory = factory
        self.enable_lifecycle = enable_lifecycle
        self.fault_engine = fault_engine
        self.effect_registry = effect_registry
        self.clearance_engine = clearance_engine
```

```python
async def execute(
    self,
    route: CompiledRoute,
    request: Request,
    path_params: Dict[str, Any],
    container: Container,
) -> Response:
```

```python
# When a parameter is typed as a Contract:
@POST("/")
async def create(self, ctx: RequestCtx, body: UserContract):
    # 'body' receives UserContract.validated_data (dict)
    # If named with _contract or _bp suffix, receives the full Contract instance
    pass
```



---

## ControllerCompiler
**URL**: `https://tubox.cloud/docs/controllers/compiler`

ControllerCompiler aquilia.controller.compiler — Compile controllers to executable routes The ControllerCompiler class scans controller classes, parses path chevrons, validates parameter types, evaluates route specificity, and identifies route conflicts. Data Structures CompiledRoute Route Specificity Each route is evaluated to assign a specificity score. Routes are evaluated from highest score to lowest: Segment Type Score Example ))} Conflict Detection ControllerEngine ControllerRouter )

### Code Examples
```python
@dataclass
class CompiledRoute:
    controller_class: type                # Controller class
    controller_metadata: ControllerMetadata   # Class metadata
    route_metadata: RouteMetadata            # Method metadata
    compiled_pattern: CompiledPattern        # Compiled regex + castors
    full_path: str                           # prefix + path
    http_method: str                         # GET, POST, etc.
    specificity: int                         # Priority score
    app_name: Optional[str] = None           # Fault namespace
```

```python
# Validates route tree for overlaps:
conflicts = compiler.validate_route_tree(compiled_controllers)
```



---

## ControllerRouter
**URL**: `https://tubox.cloud/docs/controllers/router`

ControllerRouter aquilia.controller.router — Two-tier URL matching engine The ControllerRouter matches incoming requests to compiled routes. It employs a two-tier matching strategy for maximum request throughput. Two-Tier Architecture Tier 1: Static Routes Uses a direct dictionary key lookup offering O(1) matching performance. Routes without parameters (e.g. GET /health) bypass regular expressions entirely. Tier 2: Dynamic Routes Uses compiled regex matching for routes with path chevrons (e.g. GET /users/«id:int»). Specificity sorting guarantees the correct route takes precedence. Class Definition ControllerRouteMatch Reverse URL Generation Generate paths dynamically using route names: ControllerCompiler OpenAPI Generation )

### Code Examples
```python
class ControllerRouter:
    def __init__(self):
        self.compiled_controllers: List[CompiledController] = []
        self.routes_by_method: Dict[str, List[CompiledRoute]] = {}
        self.matcher = PatternMatcher()
        self._initialized = False

        # Fast-path indexes
        self._static_routes: Dict[str, Dict[str, Tuple]] = {}
        self._dynamic_routes: Dict[str, List[Tuple]] = {}
```

```python
@dataclass
class ControllerRouteMatch:
    route: CompiledRoute       # Matched route
    params: Dict[str, Any]     # Type-cast path params
    query: Dict[str, Any]      # Validated query params
```

```python
# In handler:
url = router.url_for("UsersController.get_user", id=42)
# → "/users/42"
```



---

## Specula API Observatory
**URL**: `https://tubox.cloud/docs/controllers/openapi`

import from 'lucide-react' Specula API Observatory Specula is Aquilia's compiler-integrated API Observatory and schema compilation engine. It replaces legacy, static OpenAPI wrappers with a dynamic, metadata-enriched, introspective ASGI dashboard that exposes versions, routes, schemas, and live updates. Spec Compilation Processes compiled routing topologies, type annotations, and clearance constraints directly from memory without code scanners. Hot-Reload Streams Uses built-in Server-Sent Events (SSE) to push instant route updates to the Observatory UI during local development. Mocking & Exports Serves simulated payloads automatically from JSON schemas and exports clean Postman v2.1/Insomnia v4 catalogs. Workspace Integration Specula is registered as a typed integration in your application's workspace.py. By declaring it, the compilation phase automatically hooks routing and validation events. Removal of Legacy OpenAPI The legacy OpenAPIIntegration and its helper method Integration.openapi(...) have been completely removed. Change your configuration to use Integration.specula(...) instead. Interactive Configuration Reference Specula offers high-fidelity configuration. Select a category below to view the available attributes on SpeculaConfig / SpeculaIntegration . , , , , ].map((tab) => ( ))} , , , , ].map((item, idx) => ( Type: Default: ))} )} , , , , , ].map((item, idx) => ( Default: ))} )} , , , , , ].map((item, idx) => ( Type: bool Default: ))} )} , ].map((item, idx) => ( Type: Default: ))} )} , ].map((item, idx) => ( Type: Default: ))} )} Spec Inference & Introspection The SpeculaBuilder compiles dynamic endpoints at startup through multiple layers of static and runtime analysis: 1 Parameter Extraction URL path variables parsed by the router pattern (e.g. /users/<id:int>) are mapped directly to OpenAPI path parameters. Query parameters and custom headers are extracted from type hints and Annotated metadata. ") async def get_user( self, id: int, active: bool = True, x_client: Annotated[str, Header()] = "" ): ...`} language="python" /> 2 Request Body Extraction Specula resolves request payloads through a 4-tier strategy: request_contract argument on decorators. Method arguments annotated with a Contract type. Google-style docstring blocks: Body: "} Static code analysis searching for await ctx.json() or await ctx.form() calls. 3 Response Shapes Resolution Success status codes, content-types, and body structures are mapped from the decorator's response_model or response_contract parameters. If omitted, the engine scans the handler source code for Response.json() (JSON content), Response.html() / renderers (HTML content), and SSEResponse (text/event-stream content). Security Schemes & Clearance Detection Specula automatically detects security schemas from authentication decorators, custom pipeline guards, and role clearances: Auth Guards & Decorators Methods decorated with @authenticated or carrying auth-related guards in their pipeline (e.g. ApiKeyGuard, SessionGuard) are mapped with appropriate security schemes. Clearance System Mapping Specula detects controller-level and route-level clearances. It exposes AccessLevel values and entitlements inside custom vendor extension tags (x-specula-security). Mocking, SSE, & Integration Exports Specula is designed to make frontend integration quick and reliable. It goes beyond serving JSON to provide operational utility. M Mock Server (/specula/mock) When mock_server_enabled is active, Specula hosts a dynamic mocking endpoint. Calling it with any documented path returns synthesized mock responses matching the JSON Schema definitions, complete with mock values resolved up to mock_max_depth. S Live Refresh SSE Stream (/specula/stream) Specula handles hot reloading. It maintains an active Server-Sent Events channel. When modules reload, a spec invalidation event is pushed to the client browser, forcing the Observatory dashboard to rebuild dynamically without hard refreshes. E Postman & Insomnia Exports Download configured collection assets directly. /specula/export/postman yields a complete Postman Collection v2.1. /specula/export/insomnia yields a clean Insomnia v4 export file. ControllerRouter Configuration Overview )

### Code Examples
```python
from aquilia.workspace import Workspace
from aquilia.integrations import Integration

workspace = Workspace("payment-gateway")

# Register Specula Observatory Integration
workspace.integrate(Integration.specula(
    title="Payment Gateway API",
    version="2.1.0",
    ui_theme="dark",
    mock_server_enabled=True,
    spec_cache_ttl=120,
))
```

```python
# Extracted parameters:
# - id: integer (path, required)
# - active: boolean (query, optional, default: True)
# - x_client: string (header, required)
@GET("/users/<id:int>")
async def get_user(
    self,
    id: int,
    active: bool = True,
    x_client: Annotated[str, Header()] = ""
): ...
```

```python
# Inferred as application/json request body containing ProductCreate schema
@POST("/products")
async def create_product(
    self,
    ctx: RequestCtx,
    data: ProductCreateContract
): ...
```



---

## Body Validation
**URL**: `https://tubox.cloud/docs/controllers/validation`

Controllers Body Validation Aquilia provides declarative request body validation using the @validate_body decorator. It integrates directly with Contracts to parse and enforce contracts on incoming payloads. The @validate_body Decorator The @validate_body decorator validates incoming request payloads before they reach the route handler. On success, it injects the validated dictionary as a body keyword argument. On validation failure, it returns a 422 Unprocessable Entity response containing the validation errors. Response: # body is fully validated and typed according to the Contract contract user = await self.user_service.create(**body) return Response.json( , status=201)`} /> Validation Faults Body validation issues trigger structured faults: Fault Class Fault Code HTTP Status Description ))} Controllers Overview )

### Code Examples
```python
from aquilia import Controller, POST, RequestCtx, Response
from aquilia.controller.validation import validate_body
from myapp.users.contracts import CreateUserContract

class UsersController(Controller):
    prefix = "/users"

    @POST("/")
    @validate_body(CreateUserContract)
    async def create_user(self, ctx: RequestCtx, body: dict) -> Response:
        # body is fully validated and typed according to the Contract contract
        user = await self.user_service.create(**body)
        return Response.json({"id": user.id}, status=201)
```



---

## Pagination
**URL**: `https://tubox.cloud/docs/controllers/pagination`

Controllers Pagination Aquilia provides standard pagination strategies out of the box to paginate list responses. Supported Strategies 1. PageNumberPagination Standard page-based pagination using ?page=2&page_size=20. Works with both database QuerySets and in-memory lists. 2. LimitOffsetPagination Offset-based pagination using ?limit=20&offset=40. 3. CursorPagination Opaque cursor-based keyset pagination using ?cursor=.... Designed for large, frequently changing datasets where page skips are expensive or lead to duplicate elements. Controllers Overview )

### Code Examples
```python
from aquilia import Controller, GET
from aquilia.controller.pagination import PageNumberPagination

class ProductsController(Controller):
    @GET("/", pagination_class=PageNumberPagination)
    async def list_products(self, ctx):
        # The routing engine automatically applies the paginator
        return await Product.objects.all()
```



---

## Filtering, Searching & Ordering
**URL**: `https://tubox.cloud/docs/controllers/filters`

Controllers Filtering, Searching & Ordering Aquilia supports declarative query parameter filters, searching, and field ordering directly on route decorators. FilterSet The FilterSet class defines field matches, ranges, case-insensitive checks, null validation, or custom query overrides: ReDoS Security Guards To protect endpoints from Regular Expression Denial of Service (ReDoS) attacks, Aquilia enforces strict validation when compiling user-provided filter patterns: Pattern Length Limits: Rejects any pattern exceeding 256 characters. Dangerous Alterations: Rejects nested alternations and quantifier repetitions like (a+)+ or (a|a)+. Controllers Overview )

### Code Examples
```python
from aquilia import Controller, GET
from aquilia.controller.filters import FilterSet

class ProductFilter(FilterSet):
    class Meta:
        fields = {
            "category": ["exact"],
            "price": ["gte", "lte", "range"],
            "is_active": ["exact"],
            "name": ["icontains"],
        }

class ProductsController(Controller):
    prefix = "/products"

    @GET("/", filterset_class=ProductFilter,
         search_fields=["name", "description"],
         ordering_fields=["price", "created_at"])
    async def list_products(self, ctx):
        # Auto-filters category, price ranges, handles ?search=term and ?ordering=price
        return await Product.objects.all()
```



---

## Content Negotiation & Renderers
**URL**: `https://tubox.cloud/docs/controllers/renderers`

Controllers Content Negotiation & Renderers Aquilia handles content negotiation dynamically by parsing the client's Accept header quality factors and dispatching response payloads to pluggable renderers. Built-in Renderers Aquilia ships with a suite of highly-optimized, format-specific renderers: Renderer Class Media Type Format Suffix Config Options , , , , , ].map((row, i) => ( ))} Declaring Renderers Renderers are registered on a Controller class or overridden for individual route handlers: Authoring Custom Renderers To build a custom format serializer, subclass BaseRenderer and implement the render method: Negotiation Resolution Order Query parameter override: e.g., ?format=xml or ?format=yaml Accept Header quality factors: Parsed quality parameters (e.g. Accept: application/xml;q=0.9, application/json;q=0.8) Default: Resolves to the first renderer defined in renderer_classes (typically JSON) Controllers Overview )

### Code Examples
```python
from aquilia import Controller, GET
from aquilia.controller.renderers import JSONRenderer, XMLRenderer, YAMLRenderer

class ProductsController(Controller):
    prefix = "/products"
    renderer_classes = [JSONRenderer, XMLRenderer, YAMLRenderer]

    @GET("/")
    async def list_products(self, ctx):
        # The engine picks the renderer dynamically matching Accept q-factors
        return {"products": ["Widget", "Tool"]}
```

```python
from aquilia.controller.renderers import BaseRenderer

class CSVRenderer(BaseRenderer):
    media_type = "text/csv"
    format_suffix = "csv"
    charset = "utf-8"

    def render(self, data, *, request=None, response_status=200, response_headers=None):
        if not isinstance(data, list):
            data = [data]
        # Direct CSV formatting
        import io, csv
        output = io.StringIO()
        writer = csv.writer(output)
        if data:
            writer.writerow(data[0].keys()) # Header
            for row in data:
                writer.writerow(row.values())
        return output.getvalue()
```



---

## Routing
**URL**: `https://tubox.cloud/docs/routing`

Core / Routing Routing Aquilia features a highly optimized, compile-time routing engine. By declaring route patterns directly on controller methods via decorators, routes are parsed, analyzed, and compiled at application startup to provide near-zero matching overhead. Syntax Deprecation & Removal Warning The legacy angle bracket parameter syntax (e.g. <id:int> or «id:int») has been completely removed from the framework. Using it will result in compilation and runtime matching failures. You must use the modern curly brace format (e.g. "}) for all parameterized paths. Route Declaration & Nesting In Aquilia, controllers act as routing namespaces. The class-level prefix is automatically merged with method-level path templates during compilation: Response: # Resolves to: GET /api/articles return Response.json( ) @GET("/ ") async def get_article(self, ctx: RequestCtx, id: int) -> Response: # Resolves to: GET /api/articles/42 return Response.json( )`} /> Route Specificity Scoring Aquilia avoids matching order bugs by sorting routes mathematically based on segment specificity. When matching a path, the router evaluates routes from the highest specificity score to the lowest: Route Pattern Match Target Specificity Score ', '/users/42 (Integer segment match)', '150 (Static + Typed parameter +50)'], ['/users/ ', '/users/john (Generic string match)', '125 (Static + Untyped parameter +25)'], ['/users/*path', '/users/profile/settings (Wildcard catch-all)', '101 (Static + Splat segment +1)'] ].map(([pattern, target, score], i) => ( ))} Guides & Reference Pattern Syntax & constraints Curly brace pattern grammar, types, constraints, and validation. URL Generation Reverse path routing using url_for and query parameters. )

### Code Examples
```python
from aquilia import Controller, GET, POST, RequestCtx, Response

class ArticleController(Controller):
    prefix = "/api/articles"

    @GET("/")
    async def list_articles(self, ctx: RequestCtx) -> Response:
        # Resolves to: GET /api/articles
        return Response.json({"articles": []})

    @GET("/{id:int}")
    async def get_article(self, ctx: RequestCtx, id: int) -> Response:
        # Resolves to: GET /api/articles/42
        return Response.json({"id": id})
```



---

## Pattern Matching Syntax
**URL**: `https://tubox.cloud/docs/routing/patterns`

Routing Pattern Matching Syntax Aquilia employs a formal parameter parser that validates and casts incoming path and query parameter tokens. Legacy Syntax Removed Angle brackets/chevrons (e.g. <id:int>) are no longer supported and have been completely removed. You must use curly braces "} for all routing parameters. Parameter Grammar Definition A parameter token follows this EBNF grammar structure: This design allows you to enforce validation constraints, type-casting rules, and string transformations directly within the route template. Segment Type Reference Type Name Internal Regex Matcher Casting Result -[a-fA-F0-9] -4[a-fA-F0-9] -[89abAB][a-fA-F0-9] -[a-fA-F0-9] ', 'str (validated UUID v4)'], ['slug', '[a-z0-9-]+', 'str'], ['bool', '(true|false|1|0|yes|no)', 'bool'], ['json', '[^/]+', 'Parsed JSON object/list'] ].map(([type_, regex, casting], i) => ( name: "} ))} Constraints & ReDoS Prevention Constraints are defined by appending pipeline operators (|) to parameter declarations: min=value / max=value: Restricts numeric limits or character lengths. in=(value1,value2): Limits choices to a static set (enum validation). re="pattern": Matches a custom regular expression constraint. ReDoS Security Guard: Custom regular expression constraints are automatically analyzed for vulnerability before compile time. Patterns exceeding 256 characters or patterns using unsafe nested quantifiers (like (a+)+) are rejected immediately to protect against Denial of Service. Splats & Optional Groups Splats capture all remaining segments. Optional groups allow nested, optional sub-segments: Query Parameters & Transforms Declare query variables directly at the end of templates. Use transforms (prefixed by @) to modify parameters on-the-fly: Routing Overview URL Generation )

### Code Examples
```python
token = "{" ident [ ":" type ] [ "|" constraint_list ] [ "=" default ] [ "@" transform ] "}"
```

```python
# Splats:
@GET("/files/*path")            # path captures remaining segments as list ['a', 'b']
@GET("/download/*path:path")    # path captures segments as slash-joined string "a/b"

# Optional segments:
@GET("/posts[/{year:int}[/{month:int}]]")
# Matches: /posts, /posts/2024, /posts/2024/12
```

```python
# Query parameters mapping (?q=term&limit=10):
@GET("/search?q:str|min=1&limit:int=10")

# Parameter Transforms:
@GET("/users/{username:str@lower}")  # Casts parameter to lowercase before route handling
@GET("/articles/{title:str@strip}")  # Strips trailing and leading whitespace
```



---

## URL Generation
**URL**: `https://tubox.cloud/docs/routing/urls`

Routing URL Generation Aquilia handles reverse URL resolution by looking up registered controller method names and filling in path templates at runtime. Reverse Routing via url_for() The router exposes a url_for() method that builds routes from target method names and arguments. Route name queries support absolute names (ControllerClass.method_name) or shorthand relative method names: Prefix Nesting Resolution Prefixes are merged compile-time to maintain path structure. For example, if you register a controller inside a module that has its own sub-prefix, url_for handles the combined path automatically: Query Parameter Appends Arguments that are not defined in the route parameter template are automatically appended to the path as query variables: Exception Handling If no controller matches the name query, the router raises a structured RouteNotFoundFault: Pattern Matching Dependency Injection )

### Code Examples
```python
# Syntax: url_for("ControllerClass.method_name", **params)
url = router.url_for("ArticleController.get_article", id=42)
# → "/api/articles/42"

# Shorthand usage:
url = router.url_for("get_article", id=42)
# → "/api/articles/42"
```

```python
# Module Prefix: "/v1"
# Controller Prefix: "/users"
# Route Template: "/{id:int}"
# Resolved URL: "/v1/users/42"
```

```python
url = router.url_for("ArticleController.get_article", id=42, refresh=True, format="html")
# → "/api/articles/42?refresh=True&format=html"
```



---

## Dependency Injection Overview
**URL**: `https://tubox.cloud/docs/di`

Core Subsystems / Dependency Injection Dependency Injection Overview Aquilia's DI subsystem acts as the central nervous system of your web application. It integrates manifests, hierarchical scopes, request lifecycles, and controller resolution into a single O(1) lookup path completing in under 3&micro;s. System Architecture Core Pillars , , , , , , , , , ].map((card, i) => ( ))} Module Map The DI system lives under aquilia/di/ and is composed of these modules: Module Contents `).replace(/^_/, '')}`}> ))} Registration Flow The Registry.from_manifests() pipeline processes manifests through four sequential phases before building the container: , , , , ].map((p, i) => ( ))} from aquilia.di import Registry # Typically called by the engine during startup: registry = Registry.from_manifests( manifests=[users_manifest, orders_manifest, payments_manifest], config=app_config, enforce_cross_app=True, # Strict in production ) # Build the root container container = registry.build_container() await container.startup() # Run lifecycle hooks Resolution Hot Path resolve_async() is the primary resolution method called on every request. It is optimized for <3&micro;s cached lookups with an inlined token-to-key conversion path: # Simplified view of resolve_async internals: async def resolve_async(self, token, *, tag=None, optional=False): # 1. Inline token_to_key (avoid function-call overhead) # Uses _type_key_cache (dict) for O(1) type → string lookup key = self._type_key_cache.get(token) or self._token_to_key(token) # 2. Check cache first — O(1) dict lookup cache_key = f" : " if tag else key cached = self._cache.get(cache_key) if cached is not _SENTINEL: return cached # Usage inside Web Framework Aquilia promotes clean separation of concerns. Do not manually pull dependencies from the request container. Instead, use Constructor Injection to automatically wire services, repositories, and models. 1. Define and Annotate Services ") async def get_user(self, ctx): # Use constructor injected service directly user = await self.user_service.get_user(ctx.request.params["user_id"]) return ctx.json(user) Anti-Pattern Warning Do NOT resolve dependencies dynamically inside routes via await ctx.container.resolve_async(UserService). This hides dependencies, makes unit testing complex, and prevents compile-time dependency cycle and scope validation checks. Always prefer Constructor Injection. Provider Types at a Glance Provider Use Case Async Init `).replace(/^_/, '')}`}> ))} Error Taxonomy All DI errors inherit from DIError and include rich diagnostic messages with file locations, candidate lists, and suggested fixes: Error Trigger Suggested Fix `).replace(/^_/, '')}`}> ))} Structured faults at boot. The DI layer now raises structured DIFaults rather than bare ValueErrors. A manifest declaring an unknown scope fails fast with INVALID_SERVICE_SCOPE (always fatal, lists the valid scopes). When strict_service_registration is on, a service that fails to register raises SERVICE_REGISTRATION_FAILED and aborts boot; otherwise it logs a warning and continues. Invalid di config raises DI_CONFIG_INVALID. CLI Tooling The DI system provides five CLI commands for validation, visualization, and profiling: Command Description ))} Explore the DI Docs ))} Container )

### Code Examples
```python
from aquilia.di import Registry

# Typically called by the engine during startup:
registry = Registry.from_manifests(
    manifests=[users_manifest, orders_manifest, payments_manifest],
    config=app_config,
    enforce_cross_app=True,  # Strict in production
)

# Build the root container
container = registry.build_container()
await container.startup()  # Run lifecycle hooks
```

```python
# Simplified view of resolve_async internals:
async def resolve_async(self, token, *, tag=None, optional=False):
    # 1. Inline token_to_key (avoid function-call overhead)
    #    Uses _type_key_cache (dict) for O(1) type → string lookup
    key = self._type_key_cache.get(token) or self._token_to_key(token)
    
    # 2. Check cache first — O(1) dict lookup
    cache_key = f"{key}:{tag}" if tag else key
    cached = self._cache.get(cache_key)
    if cached is not _SENTINEL:
        return cached  # <3µs return path
    
    # 3. Scope delegation: singleton/app → parent container
    if provider.meta.scope in ("singleton", "app") and self._parent:
        return await self._parent.resolve_async(token, tag=tag)
    
    # 4. Instantiate via provider
    ctx = ResolveCtx(container=self, stack=[], cache={})
    instance = await provider.instantiate(ctx)
    
    # 5. Cache if scope is cacheable
    if self._should_cache(provider.meta.scope):
        self._cache[cache_key] = instance
        self._register_finalizer(instance)
    
    return instance
```

```python
from aquilia.di import service, Inject
from typing import Annotated

@service(scope="app")
class UserRepository:
    def __init__(self, db: DatabasePool):
        self.db = db
    
    async def find(self, user_id: str):
        return await self.db.fetch_one("SELECT * FROM users WHERE id = $1", user_id)

@service(scope="request")
class UserService:
    def __init__(
        self,
        repo: UserRepository,
        cache: Annotated[CacheBackend, Inject(tag="redis")],
    ):
        self.repo = repo
        self.cache = cache
        
    async def get_user(self, user_id: str):
        # Auto-delegates DB querying to repo
        return await self.repo.find(user_id)
```



---

## DI Container
**URL**: `https://tubox.cloud/docs/di/container`

Dependency Injection / Container DI Container The Container is the central state engine for resolved services. It manages provider lifecycle transitions, caches instances by scope, and delegates queries up hierarchical container chains. Internal Structure The Container uses __slots__ with 8 attributes for direct memory allocation, bypassing class dictionary lookups entirely: Slot Type Purpose ))} Creating Containers from aquilia.di.core import Container # Root app container (created by Registry.build_container() internally) container = Container(scope="app") # With explicit parent (for manual hierarchies) request_container = Container(scope="request", parent=container) # Preferred: use the factory method for request scoping request_container = container.create_request_scope() # → Creates child with shared _providers (by reference), fresh _cache, # and _NullLifecycle (no-op lifecycle for lightweight request containers) Note: In production web workflows, you almost never create containers manually. The Registry.build_container() method builds the root container, and the ASGI server middleware executes create_request_scope() on every incoming request automatically. API Reference register(provider, *, tag=None) Register a Provider instance. A genuine local re-registration of the same token+tag raises a DIFault, but a child container may shadow a provider inherited from its parent. Fires the on_provider_registered plugin hook. from aquilia.di import ClassProvider provider = ClassProvider(UserService, scope="request") container.register(provider) # With a tag for disambiguation container.register(redis_provider, tag="redis") bind(interface, implementation, *, scope="app", tag=None) Bind an interface type to a concrete implementation. Creates a ClassProvider internally. from abc import ABC, abstractmethod from aquilia.controller import Controller, get class IUserRepo(ABC): @abstractmethod async def find(self, id: str): ... class PostgresUserRepo(IUserRepo): def __init__(self, pool: DatabasePool): self.pool = pool async def find(self, id: str): return await self.pool.fetch_one("SELECT * FROM users WHERE id=$1", id) # Bind interface → implementation container.bind(IUserRepo, PostgresUserRepo, scope="app") # Web Controllers resolve this automatically via constructor injection: class UserController(Controller): prefix = "/users" def __init__(self, repo: IUserRepo): # Resolved to PostgresUserRepo self.repo = repo @get("/ ") async def get_user(self, ctx): user = await self.repo.find(ctx.request.params["id"]) return ctx.json(user) await resolve_async(token, *, tag=None, optional=False) Primary async resolution path. Optimized for <3&micro;s cached lookups with O(1) cache check and parent container delegation. Pass optional=True to get None instead of ProviderNotFoundError when unregistered. # Standard resolution user_svc = await container.resolve_async(UserService) # Tagged resolution redis = await container.resolve_async(CacheBackend, tag="redis") # Optional — None if not registered tracer = await container.resolve_async(Tracer, optional=True) resolve(token, *, tag=None, optional=False) Synchronous resolution for non-async call sites. Drives the async path on a persistent per-thread event loop. Raises DIResolutionFault if called from inside a running event loop — in async code, always use resolve_async. await register_instance(token, instance, scope="request", tag=None) Register a pre-built object (wraps it in a ValueProvider). Used for request-scoped objects created outside DI — the ASGI layer registers the current Request this way. Always replaces any existing entry for the token. session = await engine.open_session(request) await container.register_instance(Session, session, scope="request") is_registered(token, tag=None) Returns True if a provider is registered for the token (checks this container and its parent chain). create_request_scope() Create a lightweight child container for request-scoped isolation. The child shares the parent's providers but has isolated caches and finalizers. create_child(scope="app", *, own_lifecycle=True) Generic hierarchical child container (copy-on-write provider dict; parent singletons resolved once at the owning level). Use for per-tenant or multi-level scope trees. add_dependency_link(app_name, container) Runtime counterpart to a manifest's depends_on. When a token is missing locally and up the parent chain, resolution falls through to the linked sibling app container. Wired automatically by the runtime; undeclared cross-app deps still raise ProviderNotFoundError, and link cycles raise DependencyCycleError. await replace_provider(token, provider, *, tag=None) Production-safe atomic hot-swap of a provider (copy-on-write safe, evicts the cached instance). Distinct from the test-only override_container. Emits a REGISTRATION diagnostic event. shutdown() Runs inline Dep() generator teardowns (LIFO) first, then drains finalizers in LIFO order (clean up database connections or file handlers), runs lifecycle shutdown hooks, and clears the instance cache. Caching Behavior by Scope Scope Cached? Where Cached Behavior ))} DI Overview Providers )

### Code Examples
```python
from aquilia.di.core import Container

# Root app container (created by Registry.build_container() internally)
container = Container(scope="app")

# With explicit parent (for manual hierarchies)
request_container = Container(scope="request", parent=container)

# Preferred: use the factory method for request scoping
request_container = container.create_request_scope()
# → Creates child with shared _providers (by reference), fresh _cache,
#   and _NullLifecycle (no-op lifecycle for lightweight request containers)
```

```python
from aquilia.di import ClassProvider

provider = ClassProvider(UserService, scope="request")
container.register(provider)

# With a tag for disambiguation
container.register(redis_provider, tag="redis")
```

```python
from abc import ABC, abstractmethod
from aquilia.controller import Controller, get

class IUserRepo(ABC):
    @abstractmethod
    async def find(self, id: str): ...

class PostgresUserRepo(IUserRepo):
    def __init__(self, pool: DatabasePool):
        self.pool = pool
    
    async def find(self, id: str):
        return await self.pool.fetch_one("SELECT * FROM users WHERE id=$1", id)

# Bind interface → implementation
container.bind(IUserRepo, PostgresUserRepo, scope="app")

# Web Controllers resolve this automatically via constructor injection:
class UserController(Controller):
    prefix = "/users"

    def __init__(self, repo: IUserRepo): # Resolved to PostgresUserRepo
        self.repo = repo

    @get("/{id}")
    async def get_user(self, ctx):
        user = await self.repo.find(ctx.request.params["id"])
        return ctx.json(user)
```



---

## DI Providers
**URL**: `https://tubox.cloud/docs/di/providers`

Dependency Injection / Providers DI Providers Providers encapsulate instantiation logic. Each provider represents a contract for creating concrete services. ClassProvider The default provider type. Instantiates a class by auto-resolving constructor dependencies via inspect.signature() and type hints. Supports Annotated[Type, Inject(...)] for tagged dependencies and the async_init() convention for post-construction async initialization. Dependency Extraction The container analyzes constructor signatures at manifest loading time to construct O(1) resolution plans: ))} from aquilia.di.providers import ClassProvider from aquilia.di import Inject from typing import Annotated class OrderService: def __init__( self, repo: OrderRepository, # Untagged dep cache: Annotated[CacheBackend, Inject(tag="redis")], # Tagged dep logger: Annotated[Logger, Inject(optional=True)], # Optional dep ): self.repo = repo self.cache = cache self.logger = logger async def async_init(self): """Called after __init__ if present. Perfect for async setup.""" await self.cache.ping() # Registers in container provider = ClassProvider(OrderService, scope="request") FactoryProvider Calls a sync or async factory function to create instances. Dependencies are auto-resolved from the factory function's parameter signature. from aquilia.di.providers import FactoryProvider async def create_database_pool(config: AppConfig) -> DatabasePool: pool = await asyncpg.create_pool(dsn=config.database_url) return pool provider = FactoryProvider( token=DatabasePool, factory_fn=create_database_pool, scope="app", ) ValueProvider Returns a pre-existing object instance. Useful for configurations or external clients initialized outside the DI framework. from aquilia.di.providers import ValueProvider config = AppConfig(debug=True) provider = ValueProvider(token=AppConfig, value=config) PoolProvider Maintains an internal `asyncio.Queue` pool of instances for concurrent reuse. Resolving acquires an instance, and releasing returns it. from aquilia.di.providers import PoolProvider # Pool manages 10 instances of heavy clients provider = PoolProvider( HeavyClient, max_size=10, scope="pooled", max_waiters=256, # fast-fail once 256 callers queue on an exhausted pool ) max_waiters (default None = unbounded) caps how many callers may queue against an exhausted pool. Beyond the cap, a burst fast-fails with DIResolutionFault instead of thundering-herd queueing. The process-wide default comes from the pool_max_waiters DI setting. ContractProvider Specially designed for request validation. Instantiates a Contract validation schema by parsing and binding the incoming request payload with strict casting rules. from aquilia.di.providers import ContractProvider # Registers in container container.register(ContractProvider(UserContract, scope="request")) AliasProvider Points one token at another — resolving the alias returns the target's instance. Use it to expose the same service under multiple names or to bind an interface token to a concrete registration. from aquilia.di.providers import AliasProvider # Resolving ILogger returns whatever is registered for StructuredLogger container.register(AliasProvider(token=ILogger, target_token=StructuredLogger)) LazyProxyProvider Returns a lazy proxy that defers resolution of its target until first attribute access — the tool for breaking an otherwise-illegal construction cycle. The proxy resolves synchronously on first touch and refuses to resolve inside a running event loop (deadlock guard). from aquilia.di.providers import LazyProxyProvider # ServiceA depends on LazyB; ServiceB is built on first access. container.register(LazyProxyProvider(token=LazyB, target_token=ServiceB)) See Patterns & Recipes → Lazy Resolution for the full cycle-breaking recipe. ScopedProvider A thin wrapper that re-labels an inner provider's scope — used internally to enforce request/ephemeral semantics on a provider without rewriting it. It copies the inner metadata and overrides only the scope, delegating instantiate and shutdown to the inner provider. from aquilia.di.providers import ScopedProvider, ClassProvider inner = ClassProvider(RequestTracker) # default "app" container.register(ScopedProvider(inner, scope="request")) Automatic Provider Selection When the Registry processes a manifest service entry, it selects the appropriate provider type automatically: Condition Provider Created ))} Container Scopes )

### Code Examples
```python
from aquilia.di.providers import ClassProvider
from aquilia.di import Inject
from typing import Annotated

class OrderService:
    def __init__(
        self,
        repo: OrderRepository,                              # Untagged dep
        cache: Annotated[CacheBackend, Inject(tag="redis")], # Tagged dep
        logger: Annotated[Logger, Inject(optional=True)],    # Optional dep
    ):
        self.repo = repo
        self.cache = cache
        self.logger = logger
    
    async def async_init(self):
        """Called after __init__ if present. Perfect for async setup."""
        await self.cache.ping()

# Registers in container
provider = ClassProvider(OrderService, scope="request")
```

```python
from aquilia.di.providers import FactoryProvider

async def create_database_pool(config: AppConfig) -> DatabasePool:
    pool = await asyncpg.create_pool(dsn=config.database_url)
    return pool

provider = FactoryProvider(
    token=DatabasePool,
    factory_fn=create_database_pool,
    scope="app",
)
```

```python
from aquilia.di.providers import ValueProvider

config = AppConfig(debug=True)
provider = ValueProvider(token=AppConfig, value=config)
```



---

## Service Scopes & Lifetimes
**URL**: `https://tubox.cloud/docs/di/scopes`

Dependency Injection / Scopes Service Scopes & Lifetimes Scopes define instance lifetimes and validation constraints. Aquilia enforces strict boundary checking to prevent memory leaks and concurrency race conditions. Scope String Literals Scopes are plain string literals. Pass them anywhere a scope is expected — @service(scope="request"), provider constructors, or manifest declarations. The canonical type hint is ServiceScopeLiteral, defined in aquilia/di/scopes.py: from typing import Literal from aquilia.di import ServiceScopeLiteral ServiceScopeLiteral = Literal[ "singleton", # Process-wide lifetime "app", # Application container lifetime (alias of singleton) "request", # Isolated request lifetime "transient", # Uncached, new instance per resolution "pooled", # Managed by asyncio.Queue instance pool "ephemeral", # Request-scoped temporary lifetime ] Deprecated: the ServiceScope Enum. Accessing any member (ServiceScope.SINGLETON) or calling the Enum emits a DeprecationWarning and will be removed in a future version. Replace ServiceScope.SINGLETON with the string "singleton", ServiceScope.REQUEST with "request", and so on. String literals skip import-time namespace scanning and runtime attribute lookups. Scope Lifetime Cached Use Case ))} Choosing the Right Scope Scope is a lifetime decision. Match the instance lifetime to the data it holds: — ))} Caching & ownership. Only singleton, app, and request are cacheable. Singleton/app instances are cached at the owning (root) container and delegated upward — one instance for the process. Request instances are cached in the request child container and cleared at request shutdown. Transient and pooled are never cached in the container. Under parallel_resolution, in-flight dedup guarantees concurrent resolvers of the same uncached cacheable token still share one instance. Injection Validation To enforce structural safety, Aquilia checks scope compatibility at startup: Longer-lived scopes can always inject into shorter-lived scopes. Shorter-lived scopes CANNOT inject into longer-lived scopes (prevents memory leak state capture). Injection Compatibility Matrix Provider ↓ / Consumer → singleton app request transient ephemeral ))} ))} Scope Violation Example @service(scope="request") class RequestLogger: def __init__(self, req: Request): self.req = req @service(scope="singleton") class GlobalAnalytics: # ❌ ScopeViolationError raised at startup: # Singleton cannot depend on short-lived request scope! def __init__(self, logger: RequestLogger): self.logger = logger # Option A: Make the consumer request-scoped: @service(scope="request") class GlobalAnalytics: def __init__(self, logger: RequestLogger): self.logger = logger # Option B: Access lazily via the context container @service(scope="singleton") class GlobalAnalytics: def __init__(self): pass async def track(self, ctx_container, event: str): logger = await ctx_container.resolve_async(RequestLogger) logger.info(event) Enforcement is settings-driven. The scope_enforcement DI setting controls the outcome: "warn" (default) logs a warning, "raise" raises ScopeViolationError at startup, and "off" skips the check entirely. Configure it in your workspace.py di block — see Advanced DI. Providers Decorators )

### Code Examples
```python
from typing import Literal
from aquilia.di import ServiceScopeLiteral

ServiceScopeLiteral = Literal[
    "singleton",   # Process-wide lifetime
    "app",         # Application container lifetime (alias of singleton)
    "request",     # Isolated request lifetime
    "transient",   # Uncached, new instance per resolution
    "pooled",      # Managed by asyncio.Queue instance pool
    "ephemeral",   # Request-scoped temporary lifetime
]
```

```python
@service(scope="request")
class RequestLogger:
    def __init__(self, req: Request):
        self.req = req

@service(scope="singleton")
class GlobalAnalytics:
    # ❌ ScopeViolationError raised at startup:
    # Singleton cannot depend on short-lived request scope!
    def __init__(self, logger: RequestLogger):
        self.logger = logger
```

```python
# Option A: Make the consumer request-scoped:
@service(scope="request")
class GlobalAnalytics:
    def __init__(self, logger: RequestLogger):
        self.logger = logger

# Option B: Access lazily via the context container
@service(scope="singleton")
class GlobalAnalytics:
    def __init__(self):
        pass
        
    async def track(self, ctx_container, event: str):
        logger = await ctx_container.resolve_async(RequestLogger)
        logger.info(event)
```



---

## DI Decorators & Metadata
**URL**: `https://tubox.cloud/docs/di/decorators`

Dependency Injection / Decorators DI Decorators & Metadata Aquilia provides clear annotations under aquilia/di/decorators.py to configure scopes, inject instances, and define factory dependencies declaratively. Inject Dataclass The Inject dataclass is used within typing.Annotated hints to instruct providers on how to resolve dependencies: from dataclasses import dataclass from typing import Any, Optional @dataclass class Inject: token: Optional[Any] = None # Override resolution token tag: Optional[str] = None # Disambiguate between multiple providers optional: bool = False # Resolves to None if unregistered Usage with Annotated from typing import Annotated from aquilia.di import Inject class OrderService: def __init__( self, # Resolved by parameter type hint repo: OrderRepository, # Tagged resolution (disambiguate multiple CacheBackends) cache: Annotated[CacheBackend, Inject(tag="redis")], # Optional resolution (defaults to None if missing) metrics: Annotated[MetricsClient, Inject(optional=True)], ): self.repo = repo self.cache = cache self.metrics = metrics Internal Extraction: The container uses typing.get_type_hints(cls.__init__) to extract these metadata markers during manifest processing, creating highly optimized static execution plans. inject() A shorthand helper that generates Inject configurations: from aquilia.di import inject class OrderService: def __init__( self, cache: Annotated[CacheBackend, inject(tag="redis")] ): self.cache = cache Dep (Per-Request Dependency Injection) FastAPI-Style Injection: Dep is Aquilia's modern approach to inline route injection. It allows you to declare dependencies directly in route signatures, bypassing manifest declarations for route-specific tools. Dependencies declared in route signatures form a per-request Directed Acyclic Graph (DAG) resolved concurrently: from typing import Annotated from aquilia.di import Dep from aquilia.controller import Controller, get async def get_db_session(): async with db.session() as session: yield session class UserController(Controller): prefix = "/users" # UserController constructor injection is still used for core services def __init__(self, auth: AuthService): self.auth = auth @get("/ ") async def get_user( self, ctx, db_session: Annotated[DbSession, Dep(get_db_session)] # resolved per-request ): user = await db_session.query(User).filter_by(id=ctx.request.params["user_id"]).first() return ctx.json(user) Conditional Providers Register a service only when a predicate passes — the Spring @Profile / @ConditionalOnProperty equivalent. The predicate receives a ConditionContext carrying the active environment and config. Use the when= parameter on @service, or the standalone @conditional decorator. Both are honoured at registration when enable_conditional_providers is on (default). from aquilia.di import service, conditional, ConditionContext # Register only in production via @service(when=...) @service(when=lambda c: c.env == "prod") class RealPaymentGateway: ... # Fake gateway everywhere else @service(when=lambda c: c.env != "prod") class FakePaymentGateway: ... # Standalone @conditional — matches prod OR staging (case-insensitive) @conditional(lambda c: c.is_env("prod", "staging")) class MetricsExporter: ... # Property-based: dot-path lookup into config @conditional(lambda c: c.get("cache.backend") == "redis") class RedisCacheWarmup: ... ConditionContext is a frozen dataclass with two fields and two helpers: @dataclass(frozen=True, slots=True) class ConditionContext: env: str = "prod" # active env (AQUILIA_ENV or config "env") config: Any = None # raw config mapping/loader def get(self, path: str, default=None) -> Any: # dot-path lookup: "cache.backend" ... def is_env(self, *names: str) -> bool: # case-insensitive env match ... Safe by default: a service with no condition always registers. If a predicate raises, the service is skipped (treated as False) and boot continues — a bad predicate never crashes startup. Use should_register(target, ctx) to evaluate a predicate manually. @factory & @provides Use @factory when construction needs logic (async connect, config-driven choice). Use @provides(Token) when the factory returns an abstract/interface type and you want to bind it under that token. Both take scope (default "app"), tag, and inject their own parameters. from aquilia.di import factory, provides @factory(scope="singleton", name="db_pool") async def create_db_pool(config: AppConfig) -> DatabasePool: return await DatabasePool.connect(config.db_url) @provides(UserRepository, scope="app", tag="sql") def build_repo(db: DatabasePool) -> UserRepository: return SqlUserRepository(db) Required annotations. The ClassProvider reads constructor type hints. A parameter with no annotation and no default raises DIError at build. A parameter with a default is treated as optional and skipped by DI. Define an async def async_init(self) for construction steps that need await. Registration Decorators Decorator Scope Description , , , , , , , , ].map((row, i) => ( ))} Scopes Lifecycle )

### Code Examples
```python
from dataclasses import dataclass
from typing import Any, Optional

@dataclass
class Inject:
    token: Optional[Any] = None     # Override resolution token
    tag: Optional[str] = None       # Disambiguate between multiple providers
    optional: bool = False          # Resolves to None if unregistered
```

```python
from typing import Annotated
from aquilia.di import Inject

class OrderService:
    def __init__(
        self,
        # Resolved by parameter type hint
        repo: OrderRepository,
        
        # Tagged resolution (disambiguate multiple CacheBackends)
        cache: Annotated[CacheBackend, Inject(tag="redis")],
        
        # Optional resolution (defaults to None if missing)
        metrics: Annotated[MetricsClient, Inject(optional=True)],
    ):
        self.repo = repo
        self.cache = cache
        self.metrics = metrics
```

```python
from aquilia.di import inject

class OrderService:
    def __init__(
        self,
        cache: Annotated[CacheBackend, inject(tag="redis")]
    ):
        self.cache = cache
```



---

## Lifecycle Hooks & Disposal
**URL**: `https://tubox.cloud/docs/di/lifecycle`

Dependency Injection / Lifecycle Lifecycle Hooks & Disposal The lifecycle engine under aquilia/di/lifecycle.py manages priority-ordered startup transitions, LIFO finalization hooks, and disposal strategies. DisposalStrategy Governs the execution behavior of registered finalizers during container teardown: from aquilia.di import DisposalStrategy class DisposalStrategy(str, Enum): LIFO = "lifo" # Last-in, first-out (default) FIFO = "fifo" # First-in, first-out PARALLEL = "parallel" # Concurrent teardown via asyncio.gather Strategy Order Use Case ))} LifecycleHook Dataclass wrapping startup or teardown callbacks: from dataclasses import dataclass from typing import Callable @dataclass class LifecycleHook: name: str # Hook identifier callback: Callable # Async callable to execute priority: int = 0 # Higher priority runs FIRST phase: str = "shutdown" # "startup" or "shutdown" Register hooks manually with on_startup / on_shutdown (both take name and priority keyword args), and cleanup callbacks with register_finalizer: lifecycle = Lifecycle( disposal_strategy=DisposalStrategy.LIFO, hook_timeout=30.0, # per-hook timeout in seconds ) lifecycle.on_startup(connect_db, name="db.connect", priority=100) # runs first lifecycle.on_startup(warm_cache, name="cache.warm", priority=10) lifecycle.on_shutdown(flush_metrics, name="metrics.flush") lifecycle.register_finalizer(close_sockets) Hook Execution Semantics . ))} Auto-Detection of Lifecycle Methods The container scans registered services automatically. If a class exposes on_startup or on_shutdown, it is bound as a lifecycle hook: @service(scope="singleton") class DatabasePool: def __init__(self, config: AppConfig): self.config = config self.pool = None async def on_startup(self): """Discovered automatically: registered as a startup hook.""" self.pool = await asyncpg.create_pool(dsn=self.config.db_url) async def on_shutdown(self): """Discovered automatically: registered as a shutdown hook.""" if self.pool: await self.pool.close() Request vs App Lifecycle Aspect App Container Request Container ))} Full Lifecycle Context from aquilia.di import LifecycleContext # Build and run the app server inside a LifecycleContext container = registry.build_container() async with LifecycleContext(container): # 1. Triggers container.startup() # 2. Runs all startup hooks await run_server() # 3. Triggers container.shutdown() on block exit # 4. Cleans finalizers LIFO → shutdown hooks priority Decorators Diagnostics )

### Code Examples
```python
from aquilia.di import DisposalStrategy

class DisposalStrategy(str, Enum):
    LIFO     = "lifo"      # Last-in, first-out (default)
    FIFO     = "fifo"      # First-in, first-out
    PARALLEL = "parallel"  # Concurrent teardown via asyncio.gather
```

```python
from dataclasses import dataclass
from typing import Callable

@dataclass
class LifecycleHook:
    name: str                    # Hook identifier
    callback: Callable           # Async callable to execute
    priority: int = 0            # Higher priority runs FIRST
    phase: str = "shutdown"      # "startup" or "shutdown"
```

```python
lifecycle = Lifecycle(
    disposal_strategy=DisposalStrategy.LIFO,
    hook_timeout=30.0,   # per-hook timeout in seconds
)

lifecycle.on_startup(connect_db, name="db.connect", priority=100)   # runs first
lifecycle.on_startup(warm_cache, name="cache.warm", priority=10)
lifecycle.on_shutdown(flush_metrics, name="metrics.flush")
lifecycle.register_finalizer(close_sockets)
```



---

## RequestDAG & Inline Injection
**URL**: `https://tubox.cloud/docs/di/request-dag`

Dependency Injection / RequestDAG RequestDAG & Inline Injection The RequestDAG resolves dependencies declared inline via Dep() in route signatures. It compiles a deduplicated, concurrent execution graph per request. One engine. Aquilia previously ran two resolution engines — the Container and a separate FastAPI-Depends-style DAG. They are now unified: the container owns the single engine, and RequestDAG is a thin compatibility shim. The public API is unchanged — RequestDAG(container, request), await dag.resolve(dep, param_type), and await dag.teardown() still work — but the real work now lives in container.resolve_dep(...). All resolution state (cache, teardowns, resolving-set) is held by the container, so inline Dep() deps and constructor-injected services share one deduplicated graph. Core Execution Mechanics , , , , ].map((card, i) => ( ))} Resolution Flow Consider a route handler with deeply nested dependencies: from typing import Annotated from aquilia.di import Dep async def get_db(): print("Opening DB") yield "DB_SESSION" print("Closing DB") async def get_user_repo(db: Annotated[str, Dep(get_db)]): print("Creating UserRepo") return async def get_auth_service(db: Annotated[str, Dep(get_db)]): print("Creating AuthService") return # In your controller class: class MyController(Controller): @get("/dashboard") async def dashboard_view( self, ctx, repo: Annotated[dict, Dep(get_user_repo)], auth: Annotated[dict, Dep(get_auth_service)], ): return Execution Output Trace: Opening DB // Executed only once due to deduplication! Creating UserRepo // Resolved concurrently Creating AuthService HTTP Response sent to client Closing DB // Teardown executed in LIFO order after response Decorators Extractors )

### Code Examples
```python
from typing import Annotated
from aquilia.di import Dep

async def get_db():
    print("Opening DB")
    yield "DB_SESSION"
    print("Closing DB")

async def get_user_repo(db: Annotated[str, Dep(get_db)]):
    print("Creating UserRepo")
    return {"name": "UserRepository", "db": db}

async def get_auth_service(db: Annotated[str, Dep(get_db)]):
    print("Creating AuthService")
    return {"name": "AuthService", "db": db}

# In your controller class:
class MyController(Controller):
    @get("/dashboard")
    async def dashboard_view(
        self,
        ctx,
        repo: Annotated[dict, Dep(get_user_repo)],
        auth: Annotated[dict, Dep(get_auth_service)],
    ):
        return {"repo": repo, "auth": auth}
```



---

## HTTP Parameter Extractors
**URL**: `https://tubox.cloud/docs/di/extractors`

Dependency Injection / Extractors HTTP Parameter Extractors Bind incoming HTTP metadata directly to your dependency parameters with the built-in Header, Query, Cookie, Path, and Body extractors. Values are cast and validated through the Contract facet pipeline. How Extractors Work When the RequestDAG resolves dependencies, it checks if any parameter is annotated with an extractor dataclass. If it is, the DAG intercepts the resolution and reads the value straight from the request: from typing import Annotated from aquilia.di import Header, Query, Dep from aquilia.controller import Controller, get async def search_telemetry( user_agent: Annotated[str, Header("User-Agent")], search_query: Annotated[str, Query("q", default="")] ): print(f"Tracking search: from ") return search_query class SearchController(Controller): # Recommended constructor injection for app-wide services def __init__(self, telemetry_client: TelemetryClient): self.telemetry = telemetry_client @get("/search") async def search_view( self, ctx, query: Annotated[str, Dep(search_telemetry)] ): await self.telemetry.track("search_run") return Automatic coercion. Extracted raw strings are cast to the annotated type through the Contract facet pipeline — Annotated[int, Query("page")] yields a real int, not a string. A failed cast returns a structured BadRequestFault (HTTP 400). All five extractors accept alias to map a differently-named source key. Header Extracts an HTTP header. Lookups are case-insensitive. required defaults to True. from aquilia.di import Header @dataclass(frozen=True) class Header: name: str # header name, e.g. "Authorization" alias: str | None = None # alternate lookup key required: bool = True # missing -> BadRequestFault (HTTP 400) default: Any = None # fallback when not required # Usage async def auth(token: Annotated[str, Header("Authorization")]) -> str: return token.removeprefix("Bearer ") Query Extracts a query-string value (?key=value). required defaults to False. from aquilia.di import Query @dataclass(frozen=True) class Query: name: str | None = None # query key, e.g. "page" default: Any = None # value when absent required: bool = False # missing + required -> BadRequestFault alias: str | None = None # alternate key # Usage — cast to int with a default async def page(n: Annotated[int, Query("page", default=1)]) -> int: return n Cookie Extracts a cookie value. required defaults to False. from aquilia.di import Cookie @dataclass(frozen=True) class Cookie: name: str | None = None default: Any = None required: bool = False alias: str | None = None # Usage async def sess(sid: Annotated[str, Cookie("session_id")]) -> str: return sid Path Extracts a route/path parameter. required defaults to True. from aquilia.di import Path @dataclass(frozen=True) class Path: name: str | None = None default: Any = None required: bool = True alias: str | None = None # Usage — matches @get("/users/ "), cast to int async def load(user_id: Annotated[int, Path()]) -> int: return user_id Body Injects the parsed request body. Pair with a Contract type for full validation. from aquilia.di import Body @dataclass(frozen=True) class Body: media_type: str = "application/json" embed: bool = False # Usage async def create(data: Annotated[dict, Body()]) -> dict: return data Error Handling A missing required value, a null where null is disallowed, or a failed type cast raises BadRequestFault. The Fault Engine renders it as a structured HTTP 400 automatically — you never write the 400 yourself. RequestDAG Patterns & Recipes )

### Code Examples
```python
from typing import Annotated
from aquilia.di import Header, Query, Dep
from aquilia.controller import Controller, get

async def search_telemetry(
    user_agent: Annotated[str, Header("User-Agent")],
    search_query: Annotated[str, Query("q", default="")]
):
    print(f"Tracking search: {search_query} from {user_agent}")
    return search_query

class SearchController(Controller):
    # Recommended constructor injection for app-wide services
    def __init__(self, telemetry_client: TelemetryClient):
        self.telemetry = telemetry_client

    @get("/search")
    async def search_view(
        self,
        ctx,
        query: Annotated[str, Dep(search_telemetry)]
    ):
        await self.telemetry.track("search_run")
        return {"status": "ok", "q": query}
```

```python
from aquilia.di import Header

@dataclass(frozen=True)
class Header:
    name: str                    # header name, e.g. "Authorization"
    alias: str | None = None     # alternate lookup key
    required: bool = True        # missing -> BadRequestFault (HTTP 400)
    default: Any = None          # fallback when not required

# Usage
async def auth(token: Annotated[str, Header("Authorization")]) -> str:
    return token.removeprefix("Bearer ")
```

```python
from aquilia.di import Query

@dataclass(frozen=True)
class Query:
    name: str | None = None      # query key, e.g. "page"
    default: Any = None          # value when absent
    required: bool = False       # missing + required -> BadRequestFault
    alias: str | None = None     # alternate key

# Usage — cast to int with a default
async def page(n: Annotated[int, Query("page", default=1)]) -> int:
    return n
```



---

## DI Diagnostics & Observability
**URL**: `https://tubox.cloud/docs/di/diagnostics`

Dependency Injection / Diagnostics DI Diagnostics & Observability The diagnostics module under aquilia/di/diagnostics.py exposes runtime events, resolution timing metrics, and validation tracers. Opt-in for zero hot-path cost. Resolution events (RESOLUTION_START/SUCCESS/FAILURE) are only emitted when the diagnostics_enabled DI setting is on — keeping the default resolve path free of tracing overhead. Turn it on per-environment in your workspace.py di block (commonly DevEnv): class DevEnv(BaseEnv): class di(BaseEnv.di): diagnostics_enabled = True DIEventType Event Emitted When Metadata ))} ConsoleDiagnosticListener A built-in diagnostic listener that formats DI events to log targets. Perfect for local dev debugging: from aquilia.di import DIDiagnostics, ConsoleDiagnosticListener # Register the console diagnostic event listener listener = ConsoleDiagnosticListener() container._diagnostics.register_listener(listener) # Resolutions will now dump trace profiles into standard error: # [DI] RESOLUTION_START: token=myapp.services.UserService tag=None # [DI] PROVIDER_INSTANTIATION: token=myapp.services.UserService duration=0.0012s # [DI] RESOLUTION_SUCCESS: token=myapp.services.UserService duration=0.0014s CLI Commands Manage and check your dependency injection setup using the aq command line interface: aq di-check Verifies cyclic loops, scope matching, app isolation, and missing providers. aq di-check --settings settings.py aq di-tree Prints a clean text tree representing the entire DI hierarchy. aq di-tree --settings settings.py --root UserService aq di-graph Generates a Graphviz DOT visualization. aq di-graph --settings settings.py --out graph.dot aq di-profile Benchmarks DI cold start and warm O(1) resolution latency profiles. aq di-profile --settings settings.py --bench resolve Lifecycle )

### Code Examples
```python
class DevEnv(BaseEnv):
    class di(BaseEnv.di):
        diagnostics_enabled = True
```

```python
from aquilia.di import DIDiagnostics, ConsoleDiagnosticListener

# Register the console diagnostic event listener
listener = ConsoleDiagnosticListener()
container._diagnostics.register_listener(listener)

# Resolutions will now dump trace profiles into standard error:
# [DI] RESOLUTION_START: token=myapp.services.UserService tag=None
# [DI] PROVIDER_INSTANTIATION: token=myapp.services.UserService duration=0.0012s
# [DI] RESOLUTION_SUCCESS: token=myapp.services.UserService duration=0.0014s
```

```python
aq di-check --settings settings.py
```



---

## Advanced DI & Testing Overrides
**URL**: `https://tubox.cloud/docs/di/advanced`

Dependency Injection / Advanced Advanced DI & Testing Overrides Customize the resolution graph dynamically, swap providers at runtime during tests, and configure complex factory pipelines. Decorators Cheat Sheet Decorator Scope Description , , , , , , , ].map((row, i) => ( ))} DI Settings Every runtime knob for the container lives in one typed, immutable DISettings object. Configure it declaratively through the di section of your workspace.py — the server reads it at boot and calls configure_di() for you. from aquilia import AquilaConfig class BaseEnv(AquilaConfig): class di(AquilaConfig.DI): scope_enforcement = "warn" # "warn" | "raise" | "off" parallel_resolution = False class DevEnv(BaseEnv): class di(BaseEnv.di): diagnostics_enabled = True # trace every resolution in dev class ProdEnv(BaseEnv): class di(BaseEnv.di): scope_enforcement = "raise" # fail-fast on captive deps parallel_resolution = True # resolve independent deps concurrently pool_max_waiters = 256 # fast-fail an exhausted pool Setting Default Purpose ))} In tests or scripts you can configure the container directly. Invalid values raise DIConfigFault at construction, so bad config surfaces at boot rather than at first resolution: from aquilia.di import DISettings, configure_di, get_di_settings, reset_di_settings configure_di(DISettings(scope_enforcement="raise", parallel_resolution=True)) assert get_di_settings().strict_scopes is True # Test teardown — restore permissive defaults reset_di_settings() Provider Interceptors Interceptors wrap a provider's instantiation with around-advice (AOP) — logging, timing, tracing, caching — without touching the service class. Wrap any provider with intercept(). Interceptors run in registration order, first = outermost; call nxt() to proceed, or skip it to short-circuit with your own object. from aquilia.di import ProviderInterceptor, intercept, ClassProvider class TimingInterceptor(ProviderInterceptor): async def around_instantiate(self, ctx, nxt): import time start = time.perf_counter() obj = await nxt() # proceed to real instantiation elapsed = time.perf_counter() - start print(f"built in us") return obj # Wrap a provider — interceptors run first=outermost provider = intercept(ClassProvider(UserService, scope="app"), TimingInterceptor()) container.register(provider) intercept(P, A, B) yields the chain A(in) → B(in) → B(out) → A(out). The wrapped InterceptingProvider mirrors the inner provider's token, scope, and tags. Wrapping with an empty interceptor list raises DIFault (DI_NO_INTERCEPTORS). DI Plugins A DIPlugin hooks into registry construction to auto-register providers, observe registrations, or inspect built containers — ideal for cross-cutting concerns like auto-wiring repositories. Register once with register_plugin(); hooks fire during boot when enable_plugins is on (default). from aquilia.di import DIPlugin, register_plugin, ClassProvider class RepositoryPlugin(DIPlugin): name = "repository-autoreg" # stable id — re-registering replaces def on_registry_build(self, registry): # Runs after manifests load, before the graph is built registry.add_provider(ClassProvider(UserRepository, scope="app")) def on_provider_registered(self, container, provider): ... # fires per register() call def on_container_built(self, container): ... # fires once each app container is built register_plugin(RepositoryPlugin()) Failure-isolated: a plugin hook that raises is logged and skipped — it never crashes boot. Manage the registry with unregister_plugin(name), get_plugins(), and clear_plugins() (test teardown). Plugins are deduplicated by .name. Cross-App Links & Runtime Swaps When a module declares depends_on in its manifest, the runtime wires a dependency link between the two app containers via add_dependency_link(). A token missing locally (and up the parent chain) falls through to the linked sibling app; the owning container instantiates and caches its own singletons exactly once. Undeclared cross-app dependencies still raise ProviderNotFoundError, and link cycles raise DependencyCycleError instead of deadlocking. # Atomically replace a provider at runtime (copy-on-write safe, evicts the # cached instance). Distinct from the test-only override_container helper. await container.replace_provider(EmailService, ClassProvider(SmtpEmailService, scope="app")) # Generic hierarchical child (per-tenant trees, multi-level scopes) child = container.create_child(scope="app", own_lifecycle=True) TestRegistry Overrides Swap components with mock implementations during unit or integration testing: from aquilia.di import TestRegistry, MockProvider # Create a test registry delegating to production setup test_reg = TestRegistry(base=production_registry) # Override with custom value or MockProvider test_reg.override(EmailService, MockProvider( send=AsyncMock(return_value=True) )) # Override database connection pools with mock mocks test_reg.override(DatabasePool, value=FakeDbPool()) Pytest Fixtures Use the built-in context overrides helper to automatically mock out components during test execution: import pytest from aquilia.di.testing import override_container @pytest.mark.asyncio async def test_user_creation(client, app_container): # Override UserService inside the app DI container temporarily: mock_service = MagicMock() with override_container(app_container, ): response = await client.post("/users", json= ) assert response.status_code == 201 mock_service.create.assert_called_once() Scopes Models )

### Code Examples
```python
from aquilia import AquilaConfig

class BaseEnv(AquilaConfig):
    class di(AquilaConfig.DI):
        scope_enforcement   = "warn"     # "warn" | "raise" | "off"
        parallel_resolution = False

class DevEnv(BaseEnv):
    class di(BaseEnv.di):
        diagnostics_enabled = True       # trace every resolution in dev

class ProdEnv(BaseEnv):
    class di(BaseEnv.di):
        scope_enforcement   = "raise"    # fail-fast on captive deps
        parallel_resolution = True       # resolve independent deps concurrently
        pool_max_waiters    = 256        # fast-fail an exhausted pool
```

```python
from aquilia.di import DISettings, configure_di, get_di_settings, reset_di_settings

configure_di(DISettings(scope_enforcement="raise", parallel_resolution=True))

assert get_di_settings().strict_scopes is True

# Test teardown — restore permissive defaults
reset_di_settings()
```

```python
from aquilia.di import ProviderInterceptor, intercept, ClassProvider

class TimingInterceptor(ProviderInterceptor):
    async def around_instantiate(self, ctx, nxt):
        import time
        start = time.perf_counter()
        obj = await nxt()               # proceed to real instantiation
        elapsed = time.perf_counter() - start
        print(f"built {ctx.meta.name} in {elapsed*1e6:.1f}us")
        return obj

# Wrap a provider — interceptors run first=outermost
provider = intercept(ClassProvider(UserService, scope="app"), TimingInterceptor())
container.register(provider)
```



---

## Patterns & Real-World Recipes
**URL**: `https://tubox.cloud/docs/di/patterns`

Dependency Injection / Patterns & Recipes Patterns & Real-World Recipes A cookbook of production-tested DI patterns — from basic registration to large-scale application architecture. Every recipe is runnable and reflects the actual aquilia.di implementation. 1. Basic Service Registration The idiomatic path is declarative: decorate a class with @service and list it in your module's manifest.py. The runtime discovers it, builds a ClassProvider, and wires its constructor. Scope defaults to "app". from aquilia.di import service @service() # scope="app" (one instance per app container) class GreetingService: def greet(self, name: str) -> str: return f"Hello, !" from aquilia.aquilary import AppManifest manifest = AppManifest( name="users", services=["modules.users.services:GreetingService"], controllers=["modules.users.controllers:UsersController"], ) For programmatic setup (tests, scripts) register directly against a container: from aquilia.di import Container, ClassProvider container = Container(scope="app") container.register(ClassProvider(GreetingService, scope="app")) svc = await container.resolve_async(GreetingService) print(svc.greet("Ada")) # Hello, Ada! 2. Constructor Injection Aquilia reads type hints from __init__ and resolves each annotated parameter. No annotation and no default raises DIError at container build; a default makes the parameter optional (skipped by DI). @service() class UserRepository: def __init__(self, db: Database): # resolved by type self.db = db @service() class UserService: def __init__(self, repo: UserRepository, cache: CacheBackend): self.repo = repo self.cache = cache async def get(self, user_id: str): if cached := await self.cache.get(f"user: "): return cached user = await self.repo.find(user_id) await self.cache.set(f"user: ", user, ttl=300) return user Async construction: if a class defines an async def async_init(self) method, the ClassProvider calls it automatically after __init__ — useful when setup needs await (connect a pool, warm a cache). @service(scope="app") class SearchIndex: def __init__(self, config: AppConfig): self.config = config self.client = None async def async_init(self): self.client = await connect_elastic(self.config.es_url) 3. Factory Providers When construction needs logic — reading config, choosing an implementation, calling an async connector — use a factory. The factory's own parameters are injected too. Use @provides(Token) when the return type is abstract. from aquilia.di import factory, provides, FactoryProvider # Simple factory — token is the function @factory(scope="singleton") async def create_http_client(config: AppConfig) -> HttpClient: return HttpClient(base_url=config.api_url, timeout=config.timeout) # @provides — bind an abstract token to a concrete build @provides(PaymentGateway, scope="app", tag="live") def build_gateway(config: AppConfig) -> PaymentGateway: return StripeGateway(config.stripe_key) # Programmatic equivalent container.register(FactoryProvider(create_http_client, scope="singleton")) 4. Configuration Service A config object is the classic singleton: build it once, inject it everywhere. Bind a ready-made instance with ValueProvider (or register_instance) so DI hands back the same object without instantiating anything. from aquilia.di import ValueProvider @dataclass class AppConfig: db_url: str api_url: str timeout: float = 30.0 config = AppConfig(db_url=env("DATABASE_URL"), api_url=env("API_URL")) # Bind the concrete instance under the AppConfig token container.register(ValueProvider(value=config, token=AppConfig, scope="singleton")) # Now every service that asks for AppConfig gets this exact object @service(scope="app") class Mailer: def __init__(self, config: AppConfig): self.config = config 5. Repository & Database Pattern Bind an abstract repository interface to a concrete backend with container.bind(). Consumers depend on the interface, so you can swap SQL for in-memory in tests without touching call sites. from abc import ABC, abstractmethod class UserRepo(ABC): @abstractmethod async def find(self, user_id: str) -> User | None: ... class SqlUserRepo(UserRepo): def __init__(self, db: Database): self.db = db async def find(self, user_id: str): return await self.db.fetch_one( "SELECT * FROM users WHERE id = $1", user_id ) # parameterized — never string-format SQL # Bind interface to implementation (creates a ClassProvider internally) container.bind(UserRepo, SqlUserRepo, scope="app") @service() class ProfileService: def __init__(self, users: UserRepo): # gets SqlUserRepo self.users = users 6. Tagged Providers (Multiple Implementations) When several providers satisfy one token, disambiguate with a tag. Register each under a tag, then select one at the injection site with Inject(tag=...). Resolving an ambiguous token without a tag surfaces the mismatch. from typing import Annotated from aquilia.di import Inject, ClassProvider container.register(ClassProvider(RedisCache, scope="app"), tag="redis") container.register(ClassProvider(MemoryCache, scope="app"), tag="memory") @service() class SessionStore: def __init__( self, hot: Annotated[CacheBackend, Inject(tag="redis")], cold: Annotated[CacheBackend, Inject(tag="memory")], ): self.hot = hot self.cold = cold # Direct resolution with a tag redis = await container.resolve_async(CacheBackend, tag="redis") 7. Optional Dependencies Two ways to make a dependency optional. Both resolve to None when the provider is absent instead of raising ProviderNotFoundError: from typing import Annotated, Optional from aquilia.di import Inject @service() class AnalyticsService: def __init__( self, # (a) Optional[T] type — DI marks it optional automatically tracer: Optional[Tracer], # (b) explicit Inject(optional=True) metrics: Annotated[MetricsClient, Inject(optional=True)], ): self.tracer = tracer # None if no Tracer registered self.metrics = metrics # None if no MetricsClient registered async def record(self, event: str): if self.metrics: # guard — may be None await self.metrics.incr(event) A constructor parameter with a default value is also treated as optional and skipped by DI if unresolved. 8. Lazy Resolution (Breaking Cycles) Two singletons that need each other form a cycle the graph validator rejects. A LazyProxyProvider defers resolution until first attribute access, breaking the construction-time loop. Reach for it only when a redesign (extract an interface, use events) isn't practical. from aquilia.di import LazyProxyProvider, ClassProvider # ServiceA needs ServiceB and vice-versa. container.register(ClassProvider(ServiceB, scope="app")) # Register a lazy proxy for B under a distinct token A depends on: container.register(LazyProxyProvider(token=LazyB, target_token=ServiceB)) @service() class ServiceA: def __init__(self, b: LazyB): # gets a proxy, not a live ServiceB self._b = b # ServiceB is built on first b. access The proxy resolves synchronously on first access via a persistent per-thread event loop. It refuses to resolve inside a running event loop (would deadlock) — so the first touch must happen outside the async hot path, or you should resolve ServiceB explicitly with await. 9. Request-Scoped Services A request-scoped service lives for one HTTP request and is cached in the per-request child container. Perfect for a unit-of-work, a request-bound logger, or the current user. The ASGI layer creates and disposes the request container automatically. @service(scope="request") class UnitOfWork: def __init__(self, db: Database): # db is app-scoped, shared self.db = db self.tx = None async def async_init(self): self.tx = await self.db.begin() async def commit(self): await self.tx.commit() @service(scope="request") class OrderService: def __init__(self, uow: UnitOfWork): # same UoW for the whole request self.uow = uow Captive dependency: a singleton/app service must not inject a request-scoped one — the short-lived instance would be captured for the process lifetime. With scope_enforcement="raise" this throws ScopeViolationError at resolution. 10. Transient & Pooled Services transient builds a fresh instance on every resolve (stateless helpers, per-use builders). pooled hands out reusable instances from a bounded asyncio.Queue (heavy clients, capped concurrency). from aquilia.di import PoolProvider @service(scope="transient") class RequestIdGenerator: # new one every time it is injected def next(self) -> str: return uuid4().hex # Pool of 10 heavy clients; fast-fail if 256 callers pile up async def make_worker() -> HeavyWorker: return await HeavyWorker.connect() container.register(PoolProvider( make_worker, max_size=10, token=HeavyWorker, acquire_timeout=30.0, max_waiters=256, )) # Auto acquire/release async with pool.acquire() as worker: await worker.run(job) 11. Service Composition Compose small, single-responsibility services into higher-level ones. DI resolves the whole tree in dependency order, deduplicating shared leaves (a Database depended on by three services is built once). @service() class NotificationService: def __init__(self, mailer: Mailer, sms: SmsClient): self.mailer, self.sms = mailer, sms @service() class CheckoutService: def __init__( self, orders: OrderRepository, payments: PaymentGateway, notify: NotificationService, ): self.orders, self.payments, self.notify = orders, payments, notify async def checkout(self, cart): order = await self.orders.create(cart) await self.payments.charge(order.total) await self.notify.mailer.send(order.receipt()) return order 12. Cross-App Dependencies (depends_on) In a multi-module app, one module can consume another's services — but the edge must be declared in the manifest's depends_on. The registry validates the edge statically; the runtime wires a dependency link so resolution falls through to the owning app's container. manifest = AppManifest( name="billing", depends_on=["auth"], # billing may inject auth-owned services services=["modules.billing.services:InvoiceService"], ) @service() class InvoiceService: # AuthService is owned by the "auth" app; resolvable because # billing declares depends_on=["auth"]. def __init__(self, auth: AuthService): self.auth = auth An undeclared cross-app dependency raises CrossAppDependencyError at boot (static validation). A cycle between app links raises DependencyCycleError at resolution instead of deadlocking. The owning app instantiates and caches its singletons exactly once. 13. Plugin / Extension Scenario A DIPlugin hooks into registry construction — auto-register a family of providers, observe every registration, or inspect built containers. Ideal for a shared library that self-wires when installed. from aquilia.di import DIPlugin, register_plugin, ClassProvider class AuditPlugin(DIPlugin): name = "audit" # stable id — re-registering replaces def on_registry_build(self, registry): registry.add_provider(ClassProvider(AuditLogger, scope="app")) def on_container_built(self, container): log.info("DI container ready with audit wiring") register_plugin(AuditPlugin()) # honoured when enable_plugins=True Combine with a provider interceptor for around-advice on instantiation (timing, tracing) — see Advanced DI. 14. Testing & Mocking Swap real services for mocks without rebuilding the container. override_container is an async context manager that force-replaces a provider for the duration of a block and restores it on exit. import pytest from unittest.mock import AsyncMock from aquilia.di.testing import override_container @pytest.mark.asyncio async def test_checkout_charges_card(app_container): fake_gateway = AsyncMock() fake_gateway.charge.return_value = async with override_container(app_container, PaymentGateway, fake_gateway): checkout = await app_container.resolve_async(CheckoutService) await checkout.checkout(sample_cart) fake_gateway.charge.assert_awaited_once() For whole-suite wiring use TestRegistry (relaxed: cross-app checks off, cycles tolerated) with an overrides map, or the built-in di_container / request_container pytest fixtures. from aquilia.di import TestRegistry, MockProvider registry = TestRegistry.from_manifests( manifests, overrides= , ) container = registry.build_container() 15. Large Application Architecture At scale, lean on the manifest-first model and a few conventions: . ))} class ProdEnv(BaseEnv): class di(BaseEnv.di): scope_enforcement = "raise" # captive deps abort boot strict_service_registration = True # a bad service fails fast parallel_resolution = True # concurrent independent deps pool_max_waiters = 256 Advanced Errors & Troubleshooting )

### Code Examples
```python
from aquilia.di import service

@service()  # scope="app" (one instance per app container)
class GreetingService:
    def greet(self, name: str) -> str:
        return f"Hello, {name}!"
```

```python
from aquilia.aquilary import AppManifest

manifest = AppManifest(
    name="users",
    services=["modules.users.services:GreetingService"],
    controllers=["modules.users.controllers:UsersController"],
)
```

```python
from aquilia.di import Container, ClassProvider

container = Container(scope="app")
container.register(ClassProvider(GreetingService, scope="app"))

svc = await container.resolve_async(GreetingService)
print(svc.greet("Ada"))  # Hello, Ada!
```



---

## Errors, Faults & Troubleshooting
**URL**: `https://tubox.cloud/docs/di/troubleshooting`

Dependency Injection / Errors & Troubleshooting Errors, Faults & Troubleshooting Every DI failure raises a structured fault, not a bare exception. This page is the complete taxonomy — what each error means, when it fires, and how to fix it. The Fault Hierarchy All DI errors descend from DIFault (domain DI, severity ERROR, non-retryable, non-public). Registration/graph errors live in aquilia.di.errors and subclass DIError; runtime resolution failures raise DIResolutionFault. Because they are faults, the Fault Engine renders them as structured responses automatically. Fault └── DIFault (code varies; domain=DI) ├── DIError ("DI_ERROR") │ ├── ProviderNotFoundError ("PROVIDER_NOT_FOUND") │ ├── DependencyCycleError ("DEPENDENCY_CYCLE") │ ├── ScopeViolationError ("SCOPE_VIOLATION") │ ├── AmbiguousProviderError ("AMBIGUOUS_PROVIDER") │ ├── ManifestValidationError ("MANIFEST_VALIDATION_FAILED") │ ├── CrossAppDependencyError ("CROSS_APP_DEPENDENCY") │ ├── CircularDependencyError ("CIRCULAR_DEPENDENCY") │ └── MissingDependencyError ("MISSING_DEPENDENCY") ├── DIResolutionFault ("DI_RESOLUTION_FAILED") └── DIConfigFault ("DI_CONFIG_INVALID") Exported from aquilia.di: DIError, ProviderNotFoundError, DependencyCycleError, ScopeViolationError, AmbiguousProviderError. The graph-build errors (MissingDependencyError, CircularDependencyError, CrossAppDependencyError, ManifestValidationError) exist in aquilia.di.errors but aren't re-exported — import them from there if you catch them directly. Error Catalog , , , , , , , , , When: Fix: ))} Boot-Time Registration Faults The runtime raises structured DIFaults while wiring services from manifests: Code Cause Behavior ))} Catching DI Faults from aquilia.di import ( ProviderNotFoundError, ScopeViolationError, DependencyCycleError, DIError, ) try: svc = await container.resolve_async(SomeService) except ProviderNotFoundError as e: log.error("Missing provider: token=%s candidates=%s", e.token, e.candidates) except ScopeViolationError as e: log.error("Captive dep: %s(%s) -> %s(%s)", e.provider_token, e.provider_scope, e.consumer_token, e.consumer_scope) except DIError as e: # catch-all for the DI domain log.error("DI failure [%s]: %s", e.code, e.message) Troubleshooting Playbook ))} Validate Before You Ship Catch DI misconfiguration in CI, before it reaches production: # Fail the build on cycles, missing providers, undeclared cross-app deps aq di-check --settings workspace.py --verbose # Visualize the graph for review aq di-graph --settings workspace.py --out di-graph.dot # Inspect the resolution tree from a root aq di-tree --settings workspace.py --root modules.api.services:ApiService Patterns & Recipes Models )

### Code Examples
```python
Fault
└── DIFault                       (code varies; domain=DI)
    ├── DIError                   ("DI_ERROR")
    │   ├── ProviderNotFoundError     ("PROVIDER_NOT_FOUND")
    │   ├── DependencyCycleError      ("DEPENDENCY_CYCLE")
    │   ├── ScopeViolationError       ("SCOPE_VIOLATION")
    │   ├── AmbiguousProviderError    ("AMBIGUOUS_PROVIDER")
    │   ├── ManifestValidationError   ("MANIFEST_VALIDATION_FAILED")
    │   ├── CrossAppDependencyError   ("CROSS_APP_DEPENDENCY")
    │   ├── CircularDependencyError   ("CIRCULAR_DEPENDENCY")
    │   └── MissingDependencyError    ("MISSING_DEPENDENCY")
    ├── DIResolutionFault         ("DI_RESOLUTION_FAILED")
    └── DIConfigFault             ("DI_CONFIG_INVALID")
```

```python
from aquilia.di import (
    ProviderNotFoundError, ScopeViolationError, DependencyCycleError, DIError,
)

try:
    svc = await container.resolve_async(SomeService)
except ProviderNotFoundError as e:
    log.error("Missing provider: token=%s candidates=%s", e.token, e.candidates)
except ScopeViolationError as e:
    log.error("Captive dep: %s(%s) -> %s(%s)",
              e.provider_token, e.provider_scope, e.consumer_token, e.consumer_scope)
except DIError as e:                 # catch-all for the DI domain
    log.error("DI failure [%s]: %s", e.code, e.message)
```

```python
# Fail the build on cycles, missing providers, undeclared cross-app deps
aq di-check --settings workspace.py --verbose

# Visualize the graph for review
aq di-graph --settings workspace.py --out di-graph.dot

# Inspect the resolution tree from a root
aq di-tree --settings workspace.py --root modules.api.services:ApiService
```



---

## Models (ORM)
**URL**: `https://tubox.cloud/docs/models`

Docs / Models Models (ORM) Pure Python, async-first ORM. Subclass Model and declare fields. A metaclass collects descriptors, assigns PKs, parses Meta , registers globally, and attaches Manager . Architecture Metaclass-driven. All database access methods return an awaitable. A global ModelRegistry maps tables and dependencies. Quick Start from aquilia.models import Model from aquilia.models.fields_module import CharField, EmailField, BooleanField, DateTimeField class User(Model): table = "users" name = CharField(max_length=150) email = EmailField(unique=True) active = BooleanField(default=True) created_at = DateTimeField(auto_now_add=True) class Meta: ordering = ["-created_at"] CRUD Operations Mutations use instance methods. Queries are issued through the QuerySet attached to the objects manager. # CREATE user = User(name="Alice", email="alice@co.com") await user.save(db) # INSERT — calls save() # Eager objects manager creation user = await User.objects.create(db, name="Bob", email="bob@co.com") # READ users = await User.objects.filter(active=True).all() user = await User.objects.get(id=1) # strict one or raise # UPDATE user.name = "Alice Smith" await user.save(db, update_fields=["name"]) # UPDATE with update_fields # DELETE await user.delete_instance(db) # calls delete_instance() Identity Map and Unit of Work Aquilia deliberately does not implement an identity map or a deferred-flush unit of work, unlike session-oriented ORMs such as SQLAlchemy (Session), Hibernate (Persistence Context), or Entity Framework Core (DbContext). No identity map: fetching the same row twice returns two distinct Python objects with independent state. user_a = await User.get(id=1) user_b = await User.get(id=1) assert user_a is not user_b # Mutating user_a has no effect on user_b until saved and re-fetched. No unit of work: each .save() persists immediately — there is no deferred change batching or cross-entity flush planning. await user.save() await profile.save() await settings.save() # each of the above is a separate, immediate write # atomic() gives transactional consistency, not Session.flush()-style batching async with atomic(): await user.save() await profile.save() This is a deliberate tradeoff, not a missing feature: a session-scoped identity map and unit of work would require task-affinity tracking, session lifecycle management, and cross-request state — all at odds with an async-first framework where request handling routinely spans concurrent tasks. Explicit, immediate persistence keeps behavior predictable regardless of how your async code is scheduled. Instance Methods Method Description ))} Meta Options Configure table properties in Meta : Option Type Description ))} Model Registry Metaclass auto-registers models in ModelRegistry for dependency mapping. from aquilia.models.registry import ModelRegistry # Get model class UserModel = ModelRegistry.get("User") # Create all tables (respects FK topology order) await ModelRegistry.create_tables(db) Fields )

### Code Examples
```python
from aquilia.models import Model
from aquilia.models.fields_module import CharField, EmailField, BooleanField, DateTimeField

class User(Model):
    table = "users"

    name = CharField(max_length=150)
    email = EmailField(unique=True)
    active = BooleanField(default=True)
    created_at = DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]
```

```python
# CREATE
user = User(name="Alice", email="alice@co.com")
await user.save(db)          # INSERT — calls save()

# Eager objects manager creation
user = await User.objects.create(db, name="Bob", email="bob@co.com")

# READ
users = await User.objects.filter(active=True).all()
user  = await User.objects.get(id=1)           # strict one or raise

# UPDATE
user.name = "Alice Smith"
await user.save(db, update_fields=["name"])   # UPDATE with update_fields

# DELETE
await user.delete_instance(db)   # calls delete_instance()
```

```python
user_a = await User.get(id=1)
user_b = await User.get(id=1)

assert user_a is not user_b
# Mutating user_a has no effect on user_b until saved and re-fetched.
```



---

## Fields: Overview & Core
**URL**: `https://tubox.cloud/docs/models/fields`

Docs / Models / Fields Overview Fields: Overview & Core All fields in Aquilia ORM inherit from the base Field[T] class, implementing the Python descriptor protocol. Descriptors ensure type safety, validation, and serialization. Core Field Parameters Common options accepted by all field types: Parameter Type Default Description ))} Descriptor Contract Accessing fields is fully synchronous. Cleaned values are automatically coerced: class User(Model): name = CharField(max_length=150) # Class-level access yields the Field instance reveal_type(User.name) # -> CharField # Instance-level access yields the underlying coerced Python type user = User(name="Alice") reveal_type(user.name) # -> str Creating Custom Fields To define a custom field, inherit from Field[T] and implement sql_type(): from aquilia.models import Field from aquilia.models.fields_module import FieldValidationError class HexColorField(Field[str]): _field_type = "COLOR" _python_type = str def sql_type(self, dialect: str = "sqlite") -> str: return "VARCHAR(7)" def validate(self, value: Any) -> str: value = super().validate(value) if value is not None: if not isinstance(value, str) or not value.startswith("#") or len(value) != 7: raise FieldValidationError(self.name, "Must be a valid hex color string (e.g. #FF00FF)") return value Overview Numeric Fields )

### Code Examples
```python
class User(Model):
    name = CharField(max_length=150)

# Class-level access yields the Field instance
reveal_type(User.name)  # -> CharField

# Instance-level access yields the underlying coerced Python type
user = User(name="Alice")
reveal_type(user.name)  # -> str
```

```python
from aquilia.models import Field
from aquilia.models.fields_module import FieldValidationError

class HexColorField(Field[str]):
    _field_type = "COLOR"
    _python_type = str

    def sql_type(self, dialect: str = "sqlite") -> str:
        return "VARCHAR(7)"

    def validate(self, value: Any) -> str:
        value = super().validate(value)
        if value is not None:
            if not isinstance(value, str) or not value.startswith("#") or len(value) != 7:
                raise FieldValidationError(self.name, "Must be a valid hex color string (e.g. #FF00FF)")
        return value
```



---

## Numeric Fields
**URL**: `https://tubox.cloud/docs/models/fields/numeric`

Docs / Models / Numeric Fields Numeric Fields Aquilia provides a set of typed numeric fields representing integer, float, and decimal types. They are strictly typed and reject invalid coercions. IntegerField Types All integer fields map to standard SQL column sizes. Note that booleans are strictly rejected. Field Python Type SQL (Postgres) Range ))} Float & Decimal Fields FloatField Maps to REAL or DOUBLE PRECISION in database. score = FloatField(null=True) DecimalField Precision decimal fields. Requires max_digits and decimal_places. Maps to DECIMAL(m, d). price = DecimalField(max_digits=10, decimal_places=2) MoneyField A DecimalField subclass that adds a currency code. Same precision-safe storage as DecimalField (stored as str(), never a binary float) — the currency is metadata carried on the field, not encoded per-row. total = MoneyField(max_digits=12, decimal_places=2, currency="USD") order = await Order.create(total="149.99") order.total # Decimal('149.99') currency only validates the 3-uppercase-letter shape (not a full ISO 4217 lookup table) — a well-formed but unrecognized code is accepted on purpose: MoneyField(currency="dollars") # raises FieldValidationError immediately Auto Incremented Primary Keys Use AutoField or BigAutoField for auto-increment keys: class User(Model): # BigAutoField is default if id is omitted id = BigAutoField(primary_key=True) Fields Overview Text Fields )

### Code Examples
```python
score = FloatField(null=True)
```

```python
price = DecimalField(max_digits=10, decimal_places=2)
```

```python
total = MoneyField(max_digits=12, decimal_places=2, currency="USD")

order = await Order.create(total="149.99")
order.total  # Decimal('149.99')
```



---

## Text & String Fields
**URL**: `https://tubox.cloud/docs/models/fields/text`

Docs / Models / Text Fields Text & String Fields Expressive text fields with bounds validation, email formatting, case-insensitivity checks, and URL patterns. Field Catalogue Field SQL (SQLite / Postgres) Description ))} Case-Insensitive (CI) Fields Aquilia supports first-class case-insensitive lookups via CICharField, CIEmailField, and CITextField. Perfect for user lookups: from aquilia.models.fields_module import CICharField, CIEmailField class User(Model): username = CICharField(max_length=50, unique=True) email = CIEmailField(unique=True) EncryptedField Transparent application-layer encryption at the storage boundary. Plaintext is validated as a normal TextField on assignment; encryption/decryption happens only in to_db()/ to_python() — i.e. only on the wire to/from the database. import os from aquilia.models import Model, EncryptedField # Configure once, at app startup -- before any encrypted field is saved/read. EncryptedField.configure_encryption_key(os.environ["ENCRYPTION_KEY"]) class User(Model): email = CharField(max_length=255, unique=True) ssn = EncryptedField(null=True) user = await User.create(email="a@test.com", ssn="123-45-6789") # The "ssn" column holds ciphertext, not plaintext. reloaded = await User.get(pk=user.pk) reloaded.ssn # "123-45-6789" -- decrypted transparently on read Encryption backend priority: a custom callable pair via configure_encryption(), then Fernet (if the cryptography package is installed) or a stdlib AES-256-GCM fallback via configure_encryption_key(), and — only if nothing was ever configured — a base64 placeholder that provides no confidentiality and emits a loud UserWarning every time it's used. Configure before storing secrets: call configure_encryption_key() or configure_encryption() before any real secret is ever saved. If you see the base64 UserWarning in your logs, nothing is actually encrypted yet. Numeric Fields Date & Time Fields )

### Code Examples
```python
from aquilia.models.fields_module import CICharField, CIEmailField

class User(Model):
    username = CICharField(max_length=50, unique=True)
    email = CIEmailField(unique=True)
```

```python
import os
from aquilia.models import Model, EncryptedField

# Configure once, at app startup -- before any encrypted field is saved/read.
EncryptedField.configure_encryption_key(os.environ["ENCRYPTION_KEY"])

class User(Model):
    email = CharField(max_length=255, unique=True)
    ssn = EncryptedField(null=True)

user = await User.create(email="a@test.com", ssn="123-45-6789")
# The "ssn" column holds ciphertext, not plaintext.

reloaded = await User.get(pk=user.pk)
reloaded.ssn  # "123-45-6789" -- decrypted transparently on read
```



---

## Date & Time Fields
**URL**: `https://tubox.cloud/docs/models/fields/datetime`

Docs / Models / Date & Time Fields Date & Time Fields Fields for date, time, timezone-aware datetime instances, and timedeltas. Field Catalogue Field Python Type SQL (SQLite / Postgres) ))} Auto Timestamp Options Both DateField and DateTimeField support automatic timestamps: created_at = DateTimeField(auto_now_add=True) # Set once on creation updated_at = DateTimeField(auto_now=True) # Set on every save() Text Fields Structured Fields )

### Code Examples
```python
created_at = DateTimeField(auto_now_add=True)  # Set once on creation
updated_at = DateTimeField(auto_now=True)      # Set on every save()
```



---

## Structured & JSON Fields
**URL**: `https://tubox.cloud/docs/models/fields/structured`

Docs / Models / Structured Fields Structured & JSON Fields JSON storage, native array lists, range bounds, and key-value mapping (HStore) fields. JSONField Supported across all database backends (SQLite, PostgreSQL, MySQL). Handles serialization and deserialization of nested Python structures (lists, dicts) automatically. from aquilia.models.fields_module import JSONField class Product(Model): metadata = JSONField(default_factory=dict) Spatial Fields PointField and GeometryField are portable, GeoJSON-backed spatial fields — both subclass JSONField and store data as TEXT/JSONB exactly like any other JSON value. No PostGIS extension, no native geometry column type, no new dependency. This trades native spatial indexing/query operators for zero-setup portability across SQLite/PostgreSQL/MySQL. from aquilia.models import Model, GeometryField, PointField class Store(Model): name = CharField(max_length=100) location = PointField() class Region(Model): name = CharField(max_length=100) boundary = GeometryField(null=True) store = await Store.create( name="Flagship", location= , # [lon, lat] ) region = await Region.create( name="Downtown", boundary= , ) PointField requires '} — exactly 2 numeric coordinates. Any other shape or geometry type raises FieldValidationError. GeometryField accepts any standard GeoJSON geometry type: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection. # Rejected -- wrong geometry type for PointField await Store.create(name="X", location= ) # FieldValidationError: Expected a GeoJSON Point with 2 numeric coordinates [lon, lat] ... If you need native spatial indexes (PostGIS GIST, MySQL SPATIAL), spatial query operators (ST_Contains, ST_Distance), or geometry validation beyond well-formed GeoJSON shape, you'll want a dedicated PostGIS/spatial-extension integration — that's out of scope for this JSON-backed field pair, which optimizes for portability and zero setup. PostgreSQL Native Fields ArrayField Declared with a child field type. Compiles to native SQL array. from aquilia.models.fields_module import ArrayField, CharField tags = ArrayField(CharField(max_length=50), default_factory=list) HStoreField Stores key-value pairs where both keys and values are strings. from aquilia.models.fields_module import HStoreField attributes = HStoreField(default_factory=dict) RangeField Represents numeric or temporal intervals. Supported variants: IntegerRangeField, BigIntegerRangeField, DecimalRangeField, DateRangeField, DateTimeRangeField. from aquilia.models.fields_module import IntegerRangeField age_range = IntegerRangeField() Date & Time Fields QuerySet API )

### Code Examples
```python
from aquilia.models.fields_module import JSONField

class Product(Model):
    metadata = JSONField(default_factory=dict)
```

```python
from aquilia.models import Model, GeometryField, PointField

class Store(Model):
    name = CharField(max_length=100)
    location = PointField()

class Region(Model):
    name = CharField(max_length=100)
    boundary = GeometryField(null=True)

store = await Store.create(
    name="Flagship",
    location={"type": "Point", "coordinates": [-122.4194, 37.7749]},  # [lon, lat]
)

region = await Region.create(
    name="Downtown",
    boundary={
        "type": "Polygon",
        "coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
    },
)
```

```python
# Rejected -- wrong geometry type for PointField
await Store.create(name="X", location={"type": "Polygon", "coordinates": [...]})
# FieldValidationError: Expected a GeoJSON Point with 2 numeric coordinates [lon, lat] ...
```



---

## QuerySet API
**URL**: `https://tubox.cloud/docs/models/queryset`

Docs / Models / QuerySet API QuerySet API Immutable, clone-on-write async query builder. Chains return new QuerySet clones; terminal methods (all, first, get, count) execute SQL. Obtaining a QuerySet Access the model objects manager to start a chain: # Fresh QuerySet clone qs = User.objects.filter(active=True) # QuerySet is immutable: every chain returns a new clone q1 = User.objects.filter(active=True) q2 = q1.filter(age__gt=18) # q1 is unaffected q3 = q2.order("-created_at") # q2 is unaffected Chain Methods Method Description : m} ))} Terminal Methods (async) Method Returns Description ))} Lookups Filter using Django-style double-underscore suffixes: # Exact & Case-insensitive exact User.objects.filter(name__exact="Alice") User.objects.filter(name__iexact="alice") # Contained text User.objects.filter(email__icontains="co.com") # Range & IN checks User.objects.filter(age__range=(18, 30)) User.objects.filter(id__in=[1, 2, 3]) # Null check User.objects.filter(active__isnull=False) Q Node Composition Combine conditions using Q nodes and logical operators & (AND), | (OR), and ~ (NOT): from aquilia.models import Q # (active=True AND role="admin") OR email ends with @co.com qs = User.objects.filter( (Q(active=True) & Q(role="admin")) | Q(email__endswith="@co.com") ) # NOT suspended qs = User.objects.filter(~Q(suspended=True)) Raw WHERE / HAVING Clauses .where() and .having() accept a raw SQL fragment for cases the filter/lookup API doesn't cover. Always bind user-supplied values through ? placeholders — never string-interpolate them into the clause: # Positional placeholders qs = User.objects.where("age > ?", 18) # Named placeholders qs = User.objects.where( "status = :status AND role = :role", status="active", role="admin", ) # HAVING (use after group_by) qs = ( Order.objects .group_by("customer_id") .having("COUNT(*) > ?", 5) ) Guardrail, not the defense: both methods reject clauses containing an unparameterized DROP/ALTER/TRUNCATE/EXEC/EXECUTE/ DELETE/INSERT/UPDATE/MERGE keyword, a comment marker (--, /* */), or a bare ; — word-boundary matched, so a column named updated_at is not a false positive. This is a secondary safety net, not the actual injection defense: parameter binding is. A clause built by string-interpolating user input can still be unsafe even if it doesn't happen to contain a blocked keyword. # Rejected — SecurityFault, contains an unparameterized DML keyword await User.objects.where("id = 1; DELETE FROM users") # Rejected — comment marker await User.objects.where("id = 1 -- bypass rest of clause") # Fine — the keyword only appears inside an identifier await User.objects.where("updated_at > ?", cutoff) F Expressions Reference columns directly in SQL comparison or updates via F : from aquilia.models import F # Compare field values await User.objects.filter(login_count__gt=F("post_count")).all() # Atomic database increments await Product.objects.filter(id=42).update(stock=F("stock") - 1) Custom QuerySets Extend QuerySet to reuse domain queries: from aquilia.models import QuerySet, Manager class ArticleQuerySet(QuerySet): def published(self): return self.filter(status="published") def recent(self): return self.order("-published_at") class Article(Model): table = "articles" # Attach to objects descriptor objects = Manager.from_queryset(ArticleQuerySet)() # Usage posts = await Article.objects.published().recent().all() Fields Relationships )

### Code Examples
```python
# Fresh QuerySet clone
qs = User.objects.filter(active=True)

# QuerySet is immutable: every chain returns a new clone
q1 = User.objects.filter(active=True)
q2 = q1.filter(age__gt=18)          # q1 is unaffected
q3 = q2.order("-created_at")        # q2 is unaffected
```

```python
# Exact & Case-insensitive exact
User.objects.filter(name__exact="Alice")
User.objects.filter(name__iexact="alice")

# Contained text
User.objects.filter(email__icontains="co.com")

# Range & IN checks
User.objects.filter(age__range=(18, 30))
User.objects.filter(id__in=[1, 2, 3])

# Null check
User.objects.filter(active__isnull=False)
```

```python
from aquilia.models import Q

# (active=True AND role="admin") OR email ends with @co.com
qs = User.objects.filter(
    (Q(active=True) & Q(role="admin")) | Q(email__endswith="@co.com")
)

# NOT suspended
qs = User.objects.filter(~Q(suspended=True))
```



---

## Defining Relationships
**URL**: `https://tubox.cloud/docs/models/relationships`

Docs / Models / Defining Relationships Defining Relationships Aquilia ORM supports first-class relational fields including Many-to-One, One-to-One, and Many-to-Many configurations. ForeignKey (Many-to-One) Declares a many-to-one relationship. Requires the target model (either class reference or forward reference string) and on_delete behavior: from aquilia.models.fields_module import ForeignKey class Post(Model): # Class reference author = ForeignKey(User, on_delete="CASCADE", related_name="posts") # Or string reference (prevents circular imports) category = ForeignKey("Category", on_delete="SET_NULL", null=True) On-Delete Actions Supported database-level delete cascades: "CASCADE": Cascades the deletion of the referenced row to this row. "SET_NULL": Sets the foreign key column to NULL (requires null=True). "RESTRICT": Rejects parent deletion if dependent children rows exist. "SET_DEFAULT": Sets the column to its configured default value. "DO_NOTHING": No database-level action is taken (raw foreign key remains unchanged). OneToOneField Similar to ForeignKey, but enforces a UNIQUE constraint on the foreign key column, establishing a strict 1-to-1 link: from aquilia.models.fields_module import OneToOneField class Profile(Model): user = OneToOneField(User, on_delete="CASCADE", related_name="profile") ManyToManyField Configures a many-to-many relationship. Automatically generates an intermediary junction table: from aquilia.models.fields_module import ManyToManyField class Article(Model): tags = ManyToManyField("Tag", related_name="articles") GenericForeignKey A polymorphic relation to any registered model — Django's "virtual field" pattern. Unlike ForeignKey, it doesn't own a database column of its own: you declare two real columns yourself (a model-label column and a stringified-PK column), and GenericForeignKey resolves between them. from aquilia.models import Model, AutoField, CharField, GenericForeignKey class Comment(Model): id = AutoField(primary_key=True) body = CharField(max_length=1000) content_type = CharField(max_length=255) # e.g. "User", "Post", "Ticket" object_id = CharField(max_length=255) # stringified PK -- works for int or UUID PKs target = GenericForeignKey("content_type", "object_id") post = await Post.get(pk=1) comment = Comment(body="Nice post!") Comment.target.attach(comment, post) # sets content_type="Post", object_id=str(post.pk) await comment.save() # ... later, after loading a row back from the DB: reloaded = await Comment.get(pk=comment.pk) target = await Comment.target.resolve(reloaded) # -> the Post instance, or None Why an explicit async method, not a transparent attribute: Aquilia is async-native — there's no way to do a lazy synchronous DB fetch on plain attribute access the way Django's sync ORM can. Resolution is always await field.resolve(instance). Why no ContentType model: Django's GenericForeignKey looks up a content_type_id against a database-backed ContentType table. Aquilia reuses the already-existing, in-memory ModelRegistry.get(label) lookup — the same primitive ForeignKey already uses for string-based relation resolution — so no extra table, migration, or registry sync step is needed. Not a Field subclass — the metaclass's column-collection scan skips it entirely, so it owns no schema column and doesn't appear in generated CREATE TABLE DDL. An unset target resolves to None, not an error. QuerySet API Hydration Primitives )

### Code Examples
```python
from aquilia.models.fields_module import ForeignKey

class Post(Model):
    # Class reference
    author = ForeignKey(User, on_delete="CASCADE", related_name="posts")
    
    # Or string reference (prevents circular imports)
    category = ForeignKey("Category", on_delete="SET_NULL", null=True)
```

```python
from aquilia.models.fields_module import OneToOneField

class Profile(Model):
    user = OneToOneField(User, on_delete="CASCADE", related_name="profile")
```

```python
from aquilia.models.fields_module import ManyToManyField

class Article(Model):
    tags = ManyToManyField("Tag", related_name="articles")
```



---

## Hydration Primitives
**URL**: `https://tubox.cloud/docs/models/relationships/hydration`

Docs / Models / Hydration Primitives Hydration Primitives Aquilia's database driver is 100% async. Python descriptors are synchronous, meaning transparent lazy loading of relations on attribute access is impossible. Relationships must be explicitly hydrated. The RelatedNotLoaded Sentinel Accessing a relationship attribute that has not been hydrated returns a RelatedNotLoaded[TModel] instance. This wraps the raw foreign key value and supports no-query operations: post = await Post.objects.get(id=42) # Checking truthiness (is FK set?) — works without query if post.author: print("FK is not null") # Reading the raw PK value — works without query print(post.author.pk) # e.g., 9 print(post.author.id) # e.g., 9 # Comparing by PK — works without query if post.author == existing_user: print("Same user!") # Any other attribute access raises RelatedNotLoadedFault! try: print(post.author.name) except RelatedNotLoadedFault as e: print("Relation not loaded yet!") How to Hydrate Relations 1. Eager JOIN (select_related) Hydrates single relations (ForeignKey, OneToOneField) inside a single SQL query via a JOIN statement: # Single SQL JOIN query posts = await Post.objects.select_related("author").all() for post in posts: print(post.author.name) # No extra query! 2. Eager Batch (prefetch_related) Hydrates relations (including ManyToMany or reverse ForeignKey) using a separate query per relation, mapping results in Python: # Multi-query batching posts = await Post.objects.prefetch_related("tags").all() for post in posts: for tag in post.tags: print(tag.name) 3. Explicit Fetch (related) Loads and caches a relation on a specific instance explicitly: # Fetch and cache relation instance-level author = await post.related("author") print(author.name) Static Typing Contract Relational attributes resolve to a union type alias: Related[UserModel], which translates to: Union[UserModel, RelatedNotLoaded[UserModel], None] Annotate string-referenced relation attributes to restore strict IDE autocompletion: class Post(Model): # Required for string references author: ForeignKey[User] = ForeignKey("User", on_delete="CASCADE") Defining Relations Many-to-Many Operations )

### Code Examples
```python
post = await Post.objects.get(id=42)

# Checking truthiness (is FK set?) — works without query
if post.author:
    print("FK is not null")

# Reading the raw PK value — works without query
print(post.author.pk)  # e.g., 9
print(post.author.id)  # e.g., 9

# Comparing by PK — works without query
if post.author == existing_user:
    print("Same user!")

# Any other attribute access raises RelatedNotLoadedFault!
try:
    print(post.author.name)
except RelatedNotLoadedFault as e:
    print("Relation not loaded yet!")
```

```python
# Single SQL JOIN query
posts = await Post.objects.select_related("author").all()
for post in posts:
    print(post.author.name)  # No extra query!
```

```python
# Multi-query batching
posts = await Post.objects.prefetch_related("tags").all()
for post in posts:
    for tag in post.tags:
        print(tag.name)
```



---

## ManyToMany Operations
**URL**: `https://tubox.cloud/docs/models/relationships/m2m`

Docs / Models / ManyToMany Operations ManyToMany Operations Working with junction tables, attaching and detaching relations, and defining custom through models. Attaching and Detaching Manage relations on a saved model instance using the attach() and detach() methods: # Add a tag (ID 3) to an article instance await article.attach(db, "tags", [3]) # Remove tag (ID 3) from the article await article.detach(db, "tags", [3]) # Clear all tags await article.detach(db, "tags") Custom through Models When you need additional metadata columns on the junction table, declare a custom model class and pass it to the through argument: class User(Model): table = "users" groups = ManyToManyField("Group", through="Membership") class Group(Model): table = "groups" class Membership(Model): table = "memberships" user = ForeignKey(User, on_delete="CASCADE") group = ForeignKey(Group, on_delete="CASCADE") role = CharField(max_length=50) joined_at = DateTimeField(auto_now_add=True) Hydration Primitives Transactions )

### Code Examples
```python
# Add a tag (ID 3) to an article instance
await article.attach(db, "tags", [3])

# Remove tag (ID 3) from the article
await article.detach(db, "tags", [3])

# Clear all tags
await article.detach(db, "tags")
```

```python
class User(Model):
    table = "users"
    groups = ManyToManyField("Group", through="Membership")

class Group(Model):
    table = "groups"

class Membership(Model):
    table = "memberships"
    user = ForeignKey(User, on_delete="CASCADE")
    group = ForeignKey(Group, on_delete="CASCADE")
    role = CharField(max_length=50)
    joined_at = DateTimeField(auto_now_add=True)
```



---

## Migrations
**URL**: `https://tubox.cloud/docs/models/migrations`

Docs / Models / Migrations Migrations Aquilia's 4-layer migration system — from high-level DSL operations to raw DDL, with auto-generation, tracking, and rollback support. Architecture The migration system is organized in four layers, from highest to lowest level: Layer Module Role Auto-Generator migration_gen.py Diff current models against DB schema → generate DSL migration files DSL migration_dsl.py High-level operations: CreateModel, AddField, RunSQL, RunPython, etc. Runner migration_runner.py Execute, track, rollback, plan, status. Manages aquilia_migrations table. DDL Ops migrations.py Raw SQL builders: create/drop/rename tables, add/alter/drop columns, indexes, constraints Migration DSL Migrations are Python files in your migrations/ directory. Each file defines a Migration class with a list of operations. from aquilia.models.migration_dsl import Migration, CreateModel, AddField, CreateIndex, C class InitialMigration(Migration): """Create users and posts tables.""" dependencies = [] # no prior migration operations = [ CreateModel( name="users", columns=[ C.bigserial("id").primary_key(), C.varchar("name", 150).not_null(), C.varchar("email", 254).not_null().unique(), C.boolean("active").default(True), C.timestamp("created_at").default("NOW()"), ], ), CreateModel( name="posts", columns=[ C.bigserial("id").primary_key(), C.varchar("title", 200).not_null(), C.text("body"), C.bigint("author_id").not_null().references("users", "id", on_delete="CASCADE"), C.timestamp("published_at").nullable(), ], ), CreateIndex( table="posts", columns=["author_id"], name="idx_posts_author", ), ] DSL Operations Operation Description Reversible ))} Column Definitions — C Namespace The C class provides a fluent builder for column definitions used in CreateModel and AddField operations: from aquilia.models.migration_dsl import C # C. (name, ...) returns a ColumnDef with chainable methods: # .not_null() — add NOT NULL constraint # .nullable() — explicitly allow NULL # .primary_key() — mark as PRIMARY KEY # .unique() — add UNIQUE constraint # .default(val) — set DEFAULT value # .references(table, column, on_delete=...) — add FOREIGN KEY # .check(expr) — add CHECK constraint # Examples C.bigserial("id").primary_key() C.varchar("name", 150).not_null() C.integer("age").nullable().default(0) C.text("bio") C.boolean("active").not_null().default(True) C.timestamp("created_at").default("NOW()") C.decimal("price", 10, 2).not_null().check("price > 0") C.bigint("user_id").references("users", "id", on_delete="CASCADE") C.jsonb("metadata").default("' '") C.uuid("public_id").not_null().unique() # Available types: # C.integer, C.bigint, C.smallint, C.serial, C.bigserial # C.varchar, C.text, C.char # C.boolean # C.real, C.double, C.decimal, C.numeric # C.date, C.time, C.timestamp, C.interval # C.blob, C.bytea # C.json, C.jsonb # C.uuid # C.inet, C.cidr, C.macaddr # C.array(base_type) # C.custom(sql_type) Data Migrations Use RunSQL and RunPython for data transformations that go beyond schema changes. from aquilia.models.migration_dsl import Migration, RunSQL, RunPython async def backfill_slugs(db): """Generate slugs for existing articles.""" rows = await db.fetch_all("SELECT id, title FROM articles WHERE slug IS NULL") for row in rows: slug = row["title"].lower().replace(" ", "-")[:50] await db.execute("UPDATE articles SET slug = ? WHERE id = ?", [slug, row["id"]]) async def reverse_slugs(db): """Clear all slugs.""" await db.execute("UPDATE articles SET slug = NULL") class BackfillSlugsMigration(Migration): dependencies = ["0002_add_slug"] operations = [ # RunPython — callable with optional reverse RunPython( forward=backfill_slugs, reverse=reverse_slugs, ), # RunSQL — raw SQL with optional reverse SQL RunSQL( sql="UPDATE articles SET status = 'draft' WHERE status IS NULL", reverse_sql="UPDATE articles SET status = NULL WHERE status = 'draft'", ), ] Migration Runner The MigrationRunner handles execution, tracking, and rollback of migrations. It uses an aquilia_migrations tracking table. from aquilia.models.migration_runner import MigrationRunner # Initialize — auto-creates tracking table runner = MigrationRunner(db, migrations_dir="migrations/") await runner.init() # Status — show all migrations and their state status = await runner.status() # [ # , # , # ] # Pending — only unapplied migrations pending = await runner.get_pending() # ["0002_add_slug", "0003_backfill_slugs"] # Applied — already executed applied = await runner.get_applied() # ["0001_initial"] # Plan — dry-run showing what would execute plan = await runner.plan() # [ , ...] # sqlmigrate — view SQL without executing sql = await runner.sqlmigrate("0002_add_slug") # "ALTER TABLE articles ADD COLUMN slug VARCHAR(50);" # Migrate — apply all pending migrations await runner.migrate() # Migrate to specific target await runner.migrate(target="0002_add_slug") # Rollback — reverse the last applied migration await runner.rollback() # Rollback to specific target await runner.rollback(target="0001_initial") Auto-Generation generate_dsl_migration() compares your current model definitions against the database schema and generates a migration file with the necessary operations. from aquilia.models.migration_gen import generate_dsl_migration # Generate migration from schema diff migration_code = await generate_dsl_migration( db=db, models=[User, Post, Comment], # current model classes migrations_dir="migrations/", # where to find existing migrations name="auto", # migration name (auto-numbered) ) # The generated code is a valid Python file with: # - CreateModel for new tables # - AddField for new columns # - AlterField for changed columns # - RemoveField for deleted columns # - CreateIndex / DropIndex for index changes # Write to file with open("migrations/0004_auto.py", "w") as f: f.write(migration_code) # Review and apply await runner.migrate() Low-Level DDL — MigrationOps For advanced or dynamic schema changes, use MigrationOps directly. This is the lowest-level API that DSL operations compile into. from aquilia.models.migrations import MigrationOps ops = MigrationOps(db) # Table operations await ops.create_table("users", ) await ops.drop_table("old_table") await ops.rename_table("users", "accounts") await ops.table_exists("users") # → True # Column operations await ops.add_column("users", "age", "INTEGER DEFAULT 0") await ops.drop_column("users", "legacy_field") await ops.rename_column("users", "name", "full_name") await ops.alter_column("users", "email", "TEXT NOT NULL") await ops.column_exists("users", "age") # → True # Index operations await ops.create_index("users", ["email"], unique=True, name="idx_email") await ops.drop_index("idx_email") # Constraint operations await ops.add_constraint("users", "ck_age", "CHECK (age >= 0)") await ops.drop_constraint("users", "ck_age") # Column type helpers ops.integer() # → "INTEGER" ops.bigint() # → "BIGINT" ops.varchar(100) # → "VARCHAR(100)" ops.text() # → "TEXT" ops.boolean() # → "BOOLEAN" / "INTEGER" (SQLite) ops.timestamp() # → "TIMESTAMP" / "TIMESTAMPTZ" ops.decimal(10, 2) # → "DECIMAL(10,2)" ops.jsonb() # → "JSONB" / "TEXT" (SQLite) ops.uuid() # → "UUID" / "VARCHAR(36)" (SQLite) ops.serial() # → "SERIAL" / "INTEGER" (SQLite) ops.bigserial() # → "BIGSERIAL" / "INTEGER" (SQLite) ops.array("TEXT") # → "TEXT[]" / "TEXT" (SQLite) # Foreign key helper await ops.add_foreign_key( table="posts", column="author_id", ref_table="users", ref_column="id", on_delete="CASCADE", ) Tracking Table The runner stores migration state in aquilia_migrations: CREATE TABLE IF NOT EXISTS aquilia_migrations ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, applied TEXT NOT NULL DEFAULT (datetime('now')) ); -- Each row = one applied migration -- name: migration filename without .py extension -- applied: ISO timestamp when it was applied Migration Signals Hook into migration execution with the pre_migrate and post_migrate signals. from aquilia.models.signals import pre_migrate, post_migrate, receiver @receiver(pre_migrate) async def before_migration(sender, migration_name, **kwargs): print(f"About to apply: ") @receiver(post_migrate) async def after_migration(sender, migration_name, **kwargs): print(f"Successfully applied: ") # Good place to seed data, clear caches, etc. Relationships Signals );

### Code Examples
```python
from aquilia.models.migration_dsl import Migration, CreateModel, AddField, CreateIndex, C

class InitialMigration(Migration):
    """Create users and posts tables."""
    
    dependencies = []  # no prior migration

    operations = [
        CreateModel(
            name="users",
            columns=[
                C.bigserial("id").primary_key(),
                C.varchar("name", 150).not_null(),
                C.varchar("email", 254).not_null().unique(),
                C.boolean("active").default(True),
                C.timestamp("created_at").default("NOW()"),
            ],
        ),
        CreateModel(
            name="posts",
            columns=[
                C.bigserial("id").primary_key(),
                C.varchar("title", 200).not_null(),
                C.text("body"),
                C.bigint("author_id").not_null().references("users", "id", on_delete="CASCADE"),
                C.timestamp("published_at").nullable(),
            ],
        ),
        CreateIndex(
            table="posts",
            columns=["author_id"],
            name="idx_posts_author",
        ),
    ]
```

```python
from aquilia.models.migration_dsl import C

# C.<type>(name, ...) returns a ColumnDef with chainable methods:
# .not_null()   — add NOT NULL constraint
# .nullable()   — explicitly allow NULL
# .primary_key() — mark as PRIMARY KEY
# .unique()      — add UNIQUE constraint
# .default(val)  — set DEFAULT value
# .references(table, column, on_delete=...) — add FOREIGN KEY
# .check(expr)   — add CHECK constraint

# Examples
C.bigserial("id").primary_key()
C.varchar("name", 150).not_null()
C.integer("age").nullable().default(0)
C.text("bio")
C.boolean("active").not_null().default(True)
C.timestamp("created_at").default("NOW()")
C.decimal("price", 10, 2).not_null().check("price > 0")
C.bigint("user_id").references("users", "id", on_delete="CASCADE")
C.jsonb("metadata").default("'{}'")
C.uuid("public_id").not_null().unique()

# Available types:
# C.integer, C.bigint, C.smallint, C.serial, C.bigserial
# C.varchar, C.text, C.char
# C.boolean
# C.real, C.double, C.decimal, C.numeric
# C.date, C.time, C.timestamp, C.interval
# C.blob, C.bytea
# C.json, C.jsonb
# C.uuid
# C.inet, C.cidr, C.macaddr
# C.array(base_type)
# C.custom(sql_type)
```

```python
from aquilia.models.migration_dsl import Migration, RunSQL, RunPython

async def backfill_slugs(db):
    """Generate slugs for existing articles."""
    rows = await db.fetch_all("SELECT id, title FROM articles WHERE slug IS NULL")
    for row in rows:
        slug = row["title"].lower().replace(" ", "-")[:50]
        await db.execute("UPDATE articles SET slug = ? WHERE id = ?", [slug, row["id"]])

async def reverse_slugs(db):
    """Clear all slugs."""
    await db.execute("UPDATE articles SET slug = NULL")

class BackfillSlugsMigration(Migration):
    dependencies = ["0002_add_slug"]

    operations = [
        # RunPython — callable with optional reverse
        RunPython(
            forward=backfill_slugs,
            reverse=reverse_slugs,
        ),

        # RunSQL — raw SQL with optional reverse SQL
        RunSQL(
            sql="UPDATE articles SET status = 'draft' WHERE status IS NULL",
            reverse_sql="UPDATE articles SET status = NULL WHERE status = 'draft'",
        ),
    ]
```



---

## Advanced
**URL**: `https://tubox.cloud/docs/models/advanced`

Docs / Models / Advanced Advanced Transactions, expressions, database functions, SQL builders, constraints, and choices — the full power of Aquilia's ORM. Expression System Aquilia's expression system lets you build complex SQL expressions in Python. All expressions implement as_sql() for SQL generation. Expression Purpose Example SQL ))} When / Case Expressions Build SQL CASE WHEN expressions for conditional logic in queries. from aquilia.models.expression import When, Case, Value, F # Simple CASE WHEN users = await ( User.objects .annotate( tier=Case( When(points__gte=1000, then=Value("gold")), When(points__gte=500, then=Value("silver")), When(points__gte=100, then=Value("bronze")), default=Value("basic"), ) ) .all() ) # CASE with expressions orders = await ( Order.objects .annotate( discount_price=Case( When(quantity__gte=100, then=F("price") * Value(0.8)), When(quantity__gte=50, then=F("price") * Value(0.9)), default=F("price"), ) ) .all() ) # Conditional update await ( Product.objects .update( status=Case( When(stock=0, then=Value("out_of_stock")), When(stock__lt=10, then=Value("low_stock")), default=Value("in_stock"), ) ) ) Subqueries from aquilia.models.expression import Subquery, Exists, OuterRef # Subquery — embed a QuerySet as a scalar subquery latest_comment = ( Comment.objects .filter(post_id=OuterRef("id")) .order("-created_at") .values("text") .limit(1) ) posts = await ( Post.objects .annotate(latest_comment=Subquery(latest_comment)) .all() ) # Exists — boolean subquery for filtering has_comments = Exists( Comment.objects.filter(post_id=OuterRef("id")) ) posts_with_comments = await ( Post.objects .filter(has_comments) .all() ) # OuterRef — reference a column from the outer query # Used inside Subquery/Exists to correlate with the parent query Database Functions Built-in SQL function wrappers for use in annotations, filters, and updates: Category Functions Comparison Coalesce, Greatest, Least, NullIf String Length, Upper, Lower, Trim, LTrim, RTrim, Concat, Substr, Replace Math Abs, Round, Power Date/Time Now Type Cast, Func (custom), ExpressionWrapper from aquilia.models.expression import ( Coalesce, Greatest, Least, NullIf, Length, Upper, Lower, Trim, Concat, Substr, Replace, Abs, Round, Power, Now, Cast, Func, ExpressionWrapper, F, Value, ) # Coalesce — first non-NULL value users = await ( User.objects .annotate(display_name=Coalesce(F("nickname"), F("name"), Value("Anonymous"))) .all() ) # String functions users = await ( User.objects .annotate( name_len=Length(F("name")), upper_name=Upper(F("name")), initials=Concat(Substr(F("first_name"), 1, 1), Substr(F("last_name"), 1, 1)), ) .all() ) # Math functions products = await ( Product.objects .annotate( rounded_price=Round(F("price"), 2), abs_diff=Abs(F("price") - F("cost")), ) .all() ) # Cast — type conversion users = await ( User.objects .annotate(age_text=Cast(F("age"), "TEXT")) .all() ) # Now() — current timestamp await User.objects.filter(id=1).update(last_seen=Now()) # Greatest / Least await Product.objects.annotate( effective_price=Least(F("price"), F("sale_price")), ).all() # NullIf — return NULL if equal await User.objects.annotate( real_name=NullIf(F("name"), Value("")), ).all() SQL Builder API Low-level fluent SQL builders for when you need full control over query construction. Used internally by the Q class. from aquilia.models.sql_builder import ( SQLBuilder, InsertBuilder, UpdateBuilder, DeleteBuilder, CreateTableBuilder, AlterTableBuilder, UpsertBuilder, ) # SELECT builder sql, params = ( SQLBuilder("users") .select("id", "name", "email") .where("active = ?", True) .where("age >= ?", 18) .order_by("name ASC") .limit(10) .offset(20) .build() ) # → ("SELECT id, name, email FROM users WHERE active = ? AND age >= ? # ORDER BY name ASC LIMIT 10 OFFSET 20", [True, 18]) # INSERT builder sql, params = ( InsertBuilder("users") .columns("name", "email", "active") .values("Alice", "alice@co.com", True) .returning("id") .build() ) # UPDATE builder sql, params = ( UpdateBuilder("users") .set(name="Bob", email="bob@co.com") .where("id = ?", 42) .build() ) # DELETE builder sql, params = ( DeleteBuilder("users") .where("active = ?", False) .build() ) # CREATE TABLE builder sql = ( CreateTableBuilder("products") .column("id", "BIGSERIAL PRIMARY KEY") .column("name", "VARCHAR(200) NOT NULL") .column("price", "DECIMAL(10,2)") .if_not_exists() .build() ) # ALTER TABLE builder sql = ( AlterTableBuilder("users") .add_column("phone", "VARCHAR(20)") .build() ) # UPSERT builder (INSERT ... ON CONFLICT) sql, params = ( UpsertBuilder("users") .columns("email", "name") .values("alice@co.com", "Alice Updated") .conflict_columns("email") .update_columns("name") .build() ) Constraints from aquilia.models.constraint import CheckConstraint, ExclusionConstraint, Deferrable class Product(Model): table = "products" name = CharField(max_length=200) price = DecimalField(max_digits=10, decimal_places=2) sale_price = DecimalField(max_digits=10, decimal_places=2, null=True) class Meta: constraints = [ # Check constraint — arbitrary SQL condition CheckConstraint( check="price > 0", name="positive_price", ), # Sale price must be less than regular price CheckConstraint( check="sale_price IS NULL OR sale_price Choices — TextChoices & IntegerChoices Enum-like classes that generate (value, label) pairs for field choices. {`from aquilia.models.enums import Choices, TextChoices, IntegerChoices class Status(TextChoices): DRAFT = "draft", "Draft" REVIEW = "review", "In Review" PUBLISHED = "published", "Published" ARCHIVED = "archived", "Archived" class Priority(IntegerChoices): LOW = 1, "Low" MEDIUM = 2, "Medium" HIGH = 3, "High" CRITICAL = 4, "Critical" class Article(Model): table = "articles" title = CharField(max_length=200) status = CharField(max_length=20, choices=Status.choices, default=Status.DRAFT) priority = IntegerField(choices=Priority.choices, default=Priority.MEDIUM) # Usage article = Article(title="Test", status=Status.PUBLISHED) # Access choices Status.choices # → [("draft", "Draft"), ("review", "In Review"), ...] Status.values # → ["draft", "review", "published", "archived"] Status.labels # → ["Draft", "In Review", "Published", "Archived"] Status.names # → ["DRAFT", "REVIEW", "PUBLISHED", "ARCHIVED"] # Membership testing Status.DRAFT in Status.values # → True # Custom Choices base class class Choices: """Base class providing .choices, .values, .labels, .names properties.""" Custom Database Functions Extend the expression system with your own SQL functions using the Func base class. from aquilia.models.expression import Func, F, Value # Custom function — wraps any SQL function class DateTrunc(Func): function = "DATE_TRUNC" # Usage users = await ( User.objects .annotate( signup_month=DateTrunc(Value("month"), F("created_at")) ) .group_by("signup_month") .annotate(count=Count("id")) .order("signup_month") .values("signup_month", "count") .all() ) # Generic Func usage class JSONExtract(Func): function = "JSON_EXTRACT" data = await ( Config.objects .annotate(theme=JSONExtract(F("settings"), Value("$.theme"))) .values("id", "theme") .all() ) Aggregation Serializers );

### Code Examples
```python
from aquilia.models.expression import When, Case, Value, F

# Simple CASE WHEN
users = await (
    User.objects
    .annotate(
        tier=Case(
            When(points__gte=1000, then=Value("gold")),
            When(points__gte=500, then=Value("silver")),
            When(points__gte=100, then=Value("bronze")),
            default=Value("basic"),
        )
    )
    .all()
)

# CASE with expressions
orders = await (
    Order.objects
    .annotate(
        discount_price=Case(
            When(quantity__gte=100, then=F("price") * Value(0.8)),
            When(quantity__gte=50, then=F("price") * Value(0.9)),
            default=F("price"),
        )
    )
    .all()
)

# Conditional update
await (
    Product.objects
    .update(
        status=Case(
            When(stock=0, then=Value("out_of_stock")),
            When(stock__lt=10, then=Value("low_stock")),
            default=Value("in_stock"),
        )
    )
)
```

```python
from aquilia.models.expression import Subquery, Exists, OuterRef

# Subquery — embed a QuerySet as a scalar subquery
latest_comment = (
    Comment.objects
    .filter(post_id=OuterRef("id"))
    .order("-created_at")
    .values("text")
    .limit(1)
)

posts = await (
    Post.objects
    .annotate(latest_comment=Subquery(latest_comment))
    .all()
)

# Exists — boolean subquery for filtering
has_comments = Exists(
    Comment.objects.filter(post_id=OuterRef("id"))
)

posts_with_comments = await (
    Post.objects
    .filter(has_comments)
    .all()
)

# OuterRef — reference a column from the outer query
# Used inside Subquery/Exists to correlate with the parent query
```

```python
from aquilia.models.expression import (
    Coalesce, Greatest, Least, NullIf,
    Length, Upper, Lower, Trim, Concat, Substr, Replace,
    Abs, Round, Power,
    Now, Cast, Func, ExpressionWrapper,
    F, Value,
)

# Coalesce — first non-NULL value
users = await (
    User.objects
    .annotate(display_name=Coalesce(F("nickname"), F("name"), Value("Anonymous")))
    .all()
)

# String functions
users = await (
    User.objects
    .annotate(
        name_len=Length(F("name")),
        upper_name=Upper(F("name")),
        initials=Concat(Substr(F("first_name"), 1, 1), Substr(F("last_name"), 1, 1)),
    )
    .all()
)

# Math functions
products = await (
    Product.objects
    .annotate(
        rounded_price=Round(F("price"), 2),
        abs_diff=Abs(F("price") - F("cost")),
    )
    .all()
)

# Cast — type conversion
users = await (
    User.objects
    .annotate(age_text=Cast(F("age"), "TEXT"))
    .all()
)

# Now() — current timestamp
await User.objects.filter(id=1).update(last_seen=Now())

# Greatest / Least
await Product.objects.annotate(
    effective_price=Least(F("price"), F("sale_price")),
).all()

# NullIf — return NULL if equal
await User.objects.annotate(
    real_name=NullIf(F("name"), Value("")),
).all()
```



---

## Model Signals
**URL**: `https://tubox.cloud/docs/models/signals`

Docs / Models / Signals Model Signals Hook into the model lifecycle at every stage using pre-save, post-save, pre-delete, post-delete, pre-init, post-init, and class_prepared signals. Model Lifecycle Signals Aquilia's signals system allows decoupled applications to get notified when actions occur elsewhere. Hook into the model lifecycle at every stage: from aquilia.models.signals import ( pre_save, post_save, pre_delete, post_delete, pre_init, post_init, class_prepared, m2m_changed, receiver, ) @receiver(pre_save, sender=User) async def hash_password(sender, instance, **kwargs): if instance._state.get("password_changed"): instance.password = hash_fn(instance.password) @receiver(post_save, sender=User) async def send_notification(sender, instance, created, **kwargs): if created: await send_welcome_email(instance.email) @receiver(pre_delete, sender=User) async def check_can_delete(sender, instance, **kwargs): if instance.is_superuser: raise PermissionError("Cannot delete superuser") @receiver(class_prepared) async def on_model_registered(sender, **kwargs): print(f"Model registered: ") # Signal.connect() / Signal.disconnect() for manual management from aquilia.models.signals import Signal custom_signal = Signal() custom_signal.connect(my_handler, sender=MyModel) await custom_signal.send(sender=MyModel, instance=obj) custom_signal.disconnect(my_handler, sender=MyModel) Migrations Transactions );

### Code Examples
```python
from aquilia.models.signals import (
    pre_save, post_save, pre_delete, post_delete,
    pre_init, post_init, class_prepared,
    m2m_changed, receiver,
)

@receiver(pre_save, sender=User)
async def hash_password(sender, instance, **kwargs):
    if instance._state.get("password_changed"):
        instance.password = hash_fn(instance.password)

@receiver(post_save, sender=User)
async def send_notification(sender, instance, created, **kwargs):
    if created:
        await send_welcome_email(instance.email)

@receiver(pre_delete, sender=User)
async def check_can_delete(sender, instance, **kwargs):
    if instance.is_superuser:
        raise PermissionError("Cannot delete superuser")

@receiver(class_prepared)
async def on_model_registered(sender, **kwargs):
    print(f"Model registered: {sender.__name__}")

# Signal.connect() / Signal.disconnect() for manual management
from aquilia.models.signals import Signal

custom_signal = Signal()
custom_signal.connect(my_handler, sender=MyModel)
await custom_signal.send(sender=MyModel, instance=obj)
custom_signal.disconnect(my_handler, sender=MyModel)
```



---

## Transactions: Atomic Contexts
**URL**: `https://tubox.cloud/docs/models/transactions`

Docs / Models / Transactions Transactions: Atomic Contexts Aquilia transaction manager supports decorators, context blocks, explicit isolation levels, read-only routing, watchdog timeout constraints, and durability safety checks. Atomic Usage Provide transaction safety with atomic context blocks or decorators: from aquilia.models.transactions import atomic # Context Manager async with atomic(): user = await User.create(name="Alice") await Profile.create(user=user.id) # Decorator @atomic() async def make_purchase(user_id, item_id): await User.objects.filter(id=user_id).update(balance=F("balance") - 10) await Order.create(user_id=user_id, item_id=item_id) Advanced Options Isolation Levels Configure SQL isolation level on PostgreSQL or MySQL: # Supports: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE async with atomic(isolation="SERIALIZABLE"): ... Read-Only Transactions On SQLite, readonly=True routes queries to a reader connection pool, avoiding locking contentions with the database writer: async with atomic(readonly=True): users = await User.objects.all() Watchdog Timeout Cancel the block and trigger a rollback if execution exceeds the configured duration: # Raises QueryFault if block takes longer than 5 seconds async with atomic(timeout=5.0): await long_running_query() Durability Safety Use durable=True to ensure this transaction block is strictly the outermost block, preventing nesting: async with atomic(durable=True): # Fails with QueryFault if called inside another transaction block ... Many-to-Many Operations Savepoints & Nesting )

### Code Examples
```python
from aquilia.models.transactions import atomic

# Context Manager
async with atomic():
    user = await User.create(name="Alice")
    await Profile.create(user=user.id)

# Decorator
@atomic()
async def make_purchase(user_id, item_id):
    await User.objects.filter(id=user_id).update(balance=F("balance") - 10)
    await Order.create(user_id=user_id, item_id=item_id)
```

```python
# Supports: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE
async with atomic(isolation="SERIALIZABLE"):
    ...
```

```python
async with atomic(readonly=True):
    users = await User.objects.all()
```



---

## Savepoints & Nesting
**URL**: `https://tubox.cloud/docs/models/transactions/savepoints`

Docs / Models / Savepoints & Nesting Savepoints & Nesting Nesting transaction blocks automatically maps to SQL SAVEPOINT statements, allowing selective inner rollbacks. Nesting and Isolation The outermost atomic() block initiates a transaction. Nested atomic() blocks create savepoints. Exceptions in nested blocks must be caught to prevent rolling back the parent block: async with atomic() as sp1: await User.create(name="Bob") try: async with atomic() as sp2: await Post.create(title="Hello") raise ValueError("nested exception") # sp2 rolls back here except ValueError: pass # Exception is caught; sp1 remains active and uncompromised # Bob will be saved, Post will be rolled back Atomic & Contexts Lifecycle Hooks )

### Code Examples
```python
async with atomic() as sp1:
    await User.create(name="Bob")
    
    try:
        async with atomic() as sp2:
            await Post.create(title="Hello")
            raise ValueError("nested exception")  # sp2 rolls back here
    except ValueError:
        pass  # Exception is caught; sp1 remains active and uncompromised

    # Bob will be saved, Post will be rolled back
```



---

## Transaction Hooks
**URL**: `https://tubox.cloud/docs/models/transactions/hooks`

Docs / Models / Transaction Hooks Transaction Hooks Register post-commit or post-rollback hook callbacks safely. Registering Callbacks Both sync and async callables are supported. on_commit hooks only fire when the outermost transaction successfully commits: async with atomic() as txn: await Order.create(total=100) # Commit callback (outermost only) txn.on_commit(lambda: send_email("order confirmed")) # Rollback callback txn.on_rollback(lambda: log_failure("order failed")) Execution Safety & Isolation Hooks are isolated: if one hook fails and raises an exception, the exception is logged but suppressed. This ensures that a single failed hook callback does not interrupt other registered hooks or corrupt already-completed database actions. Savepoints & Nesting Signals )

### Code Examples
```python
async with atomic() as txn:
    await Order.create(total=100)
    
    # Commit callback (outermost only)
    txn.on_commit(lambda: send_email("order confirmed"))
    
    # Rollback callback
    txn.on_rollback(lambda: log_failure("order failed"))
```



---

## Aggregation
**URL**: `https://tubox.cloud/docs/models/aggregation`

Docs / Models / Aggregation Aggregation Computing database summary values using Sum, Avg, Count, Max, Min, and database group-by operations. Database Aggregates Aggregate functions compute summary values. Use .aggregate() for whole-table aggregates or .annotate() with .group_by() for per-group. Function SQL Notes ))} from aquilia.models.aggregate import Sum, Avg, Count, Max, Min # Whole-table aggregate stats = await Order.objects.aggregate( total=Sum("amount"), avg_amount=Avg("amount"), order_count=Count("id"), max_amount=Max("amount"), ) # → # Per-group annotation by_category = await ( Product.objects .annotate(total_sales=Sum("sales")) .group_by("category") .order("-total_sales") .values("category", "total_sales") .all() ) # → [ , ...] # PostgreSQL-specific aggregates from aquilia.models.aggregate import ArrayAgg, StringAgg grouped = await ( Tag.objects .annotate( names=ArrayAgg("name"), csv=StringAgg("name", delimiter=", "), ) .group_by("category") .values("category", "names", "csv") .all() ) Transactions Advanced );

### Code Examples
```python
from aquilia.models.aggregate import Sum, Avg, Count, Max, Min

# Whole-table aggregate
stats = await Order.objects.aggregate(
    total=Sum("amount"),
    avg_amount=Avg("amount"),
    order_count=Count("id"),
    max_amount=Max("amount"),
)
# → {"total": 50000, "avg_amount": 250.0, "order_count": 200, "max_amount": 999}

# Per-group annotation
by_category = await (
    Product.objects
    .annotate(total_sales=Sum("sales"))
    .group_by("category")
    .order("-total_sales")
    .values("category", "total_sales")
    .all()
)
# → [{"category": "Electronics", "total_sales": 50000}, ...]

# PostgreSQL-specific aggregates
from aquilia.models.aggregate import ArrayAgg, StringAgg

grouped = await (
    Tag.objects
    .annotate(
        names=ArrayAgg("name"),
        csv=StringAgg("name", delimiter=", "),
    )
    .group_by("category")
    .values("category", "names", "csv")
    .all()
)
```



---

## Window Functions
**URL**: `https://tubox.cloud/docs/models/window-functions`

Docs / Models / Window Functions Window Functions Compute values across related rows without collapsing them — rankings, running totals, moving averages, and more. v1.3.3+ Concept A window function operates on a set of rows related to the current row — defined by an OVER clause — and returns a value for each row individually. Unlike aggregate functions used with GROUP BY, window functions do not collapse rows. Every input row receives its own output row, with the window function result added as an annotation. The canonical use cases are: Ranking — RANK(), DENSE_RANK(), ROW_NUMBER() per partition Running totals — SUM() OVER ordered window Moving averages — AVG() OVER frame clause Lead/lag comparisons — LAG() and LEAD() for period-over-period Top-N per group — rank within partition, then filter in Python or subquery Key difference from GROUP BY: GROUP BY collapses many rows into one aggregate row. Window functions keep all rows and add a computed column. Use GROUP BY when you want one row per group; use window functions when you want all rows with per-row context. Imports # Top-level import — everything exported from aquilia.models from aquilia.models import ( Window, Rank, DenseRank, RowNumber, Ntile, Lag, Lead, FirstValue, LastValue, NthValue, FrameType, FrameBound, WindowFrame, Sum, Avg, Count, # aggregates work as window functions too F, OrderBy, ) # Or import from the window module directly from aquilia.models.window import Window, Rank, FrameBound, WindowFrame The Window() Wrapper Window wraps any window function or aggregate expression with an OVER clause. It is used inside .annotate() just like any other expression. Parameter Type Description ))} # Window generates: RANK() OVER (PARTITION BY "country" ORDER BY "score" DESC) result = await User.objects.annotate( rank=Window(Rank(), partition_by=['country'], order_by='-score') ).all() # Access annotation on each row: for user in result: print(user.rank, user.name) # 1 Alice, 2 Bob, ... Ranking Functions Ranking functions assign a position to each row within its partition. They require an ORDER BY clause in the window to be meaningful; without it, all rows receive the same rank. Class SQL Tie Handling ))} from aquilia.models import Rank, DenseRank, RowNumber, Ntile, Window # Leaderboard: rank players per game, ordered by score DESC leaderboard = await PlayerScore.objects.annotate( rank=Window(Rank(), partition_by=['game_id'], order_by='-score'), dense_rank=Window(DenseRank(), partition_by=['game_id'], order_by='-score'), row_num=Window(RowNumber(), partition_by=['game_id'], order_by='-score'), ).order('game_id', 'rank').all() # Percentile buckets: split each department into 4 salary quartiles quartiles = await Employee.objects.annotate( quartile=Window(Ntile(4), partition_by=['department_id'], order_by='salary') ).all() # quartile=1 → lowest 25%, quartile=4 → top 25% Value Functions: Lag, Lead, First/Last/Nth Value functions look at other rows in the window relative to the current row or access boundary values. Class SQL Description ))} from aquilia.models import Lag, Lead, FirstValue, LastValue, NthValue, Window, F # Month-over-month revenue change monthly = await MonthlySales.objects.annotate( prev_month_revenue=Window( Lag(F('revenue'), offset=1, default=0), partition_by=['product_id'], order_by='month', ) ).all() # pct_change computed in Python after fetching: for row in monthly: if row.prev_month_revenue: row.pct_change = (row.revenue - row.prev_month_revenue) / row.prev_month_revenue # Rolling 3-day lookahead orders = await DailyOrder.objects.annotate( next_3_days=Window( Lead(F('order_count'), offset=3, default=0), partition_by=['region'], order_by='date', ) ).all() # Cheapest item in department (frame: all rows in partition) products = await Product.objects.annotate( cheapest_in_dept=Window( FirstValue(F('price')), partition_by=['department_id'], order_by='price', ) ).all() Aggregates as Window Functions Any aggregate expression (Sum, Avg, Count, Max, Min) can be placed inside Window(). The aggregate then computes over the rows in the window frame instead of the whole group. from aquilia.models import Sum, Avg, Count, Window, F # Running total of sales per region, ordered by date sales = await Sale.objects.annotate( running_total=Window( Sum(F('amount')), partition_by=['region'], order_by='sale_date', ) ).order('region', 'sale_date').all() # 7-day moving average of page views from aquilia.models import WindowFrame, FrameType, FrameBound seven_day_avg = await PageView.objects.annotate( moving_avg=Window( Avg(F('views')), partition_by=['page_id'], order_by='date', frame=WindowFrame( FrameType.ROWS, start=FrameBound.preceding(6), end=FrameBound.current_row(), ) ) ).all() # Cumulative count of orders per customer up to current order orders = await Order.objects.annotate( cumulative_orders=Window( Count(F('id')), partition_by=['customer_id'], order_by='created_at', ) ).all() PARTITION BY & ORDER BY partition_by divides rows into independent groups; the window function resets at each group boundary. order_by within the window controls how rows are sequenced inside each partition. from aquilia.models import Window, Rank, F, OrderBy # Single partition column (string shorthand) Window(Rank(), partition_by='department_id', order_by='-salary') # Multiple partition columns Window(Rank(), partition_by=['country', 'city'], order_by='-score') # F() objects instead of strings Window(Rank(), partition_by=[F('country'), F('city')], order_by='-score') # Mixed ascending/descending with explicit OrderBy Window( Rank(), partition_by=['department_id'], order_by=[OrderBy(F('salary'), descending=True), 'name'], ) # No partition — window spans entire result set Window(Rank(), order_by='-score') # Global rank across all rows Frame Clauses Frame clauses restrict which rows within the ordered window participate in the aggregate. They only apply to aggregate-style window functions (Sum, Avg, etc.) — pure ranking functions ignore frames. FrameType Meaning Support ))} from aquilia.models import WindowFrame, FrameType, FrameBound, Window, Avg, F # Unbounded running total (from first row to current row) WindowFrame( FrameType.ROWS, start=FrameBound.unbounded_preceding(), end=FrameBound.current_row(), ) # 7-row sliding window (3 before, current, 3 after) WindowFrame( FrameType.ROWS, start=FrameBound.preceding(3), end=FrameBound.following(3), ) # Entire partition WindowFrame( FrameType.ROWS, start=FrameBound.unbounded_preceding(), end=FrameBound.unbounded_following(), ) # Example: 30-day moving average thirty_day_ma = await DailyStat.objects.annotate( ma_30=Window( Avg(F('value')), order_by='date', frame=WindowFrame( FrameType.ROWS, start=FrameBound.preceding(29), end=FrameBound.current_row(), ) ) ).all() Production Scenarios Top-N Per Group SQL does not allow filtering on window annotation aliases directly in WHERE (SQL engine restriction — window functions execute after WHERE). Fetch via a CTE or subquery, then filter in Python or wrap in a CTE: from aquilia.models import Window, RowNumber, F # Fetch top-3 posts per author (filter in Python after fetch) posts = await Post.objects.annotate( rn=Window(RowNumber(), partition_by=['author_id'], order_by='-likes') ).all() top3 = [p for p in posts if p.rn Year-over-Year Comparison ))} Limitations & Gotchas ⚠ Cannot filter on window annotations in WHERE — SQL evaluates window functions after WHERE and GROUP BY. Use a CTE or subquery to filter on window results. ⚠ Cannot use window annotations in GROUP BY — Window expressions may not appear in GROUP BY columns. ⚠ Ntile parameter is a bind value — Ntile(n) passes n as a parameter, not inlined SQL. This is correct and safe. ✓ Placeholders use ? — All Aquilia backends use positional ? placeholders. The backend layer translates as needed. Aggregation Common Table Expressions );

### Code Examples
```python
# Top-level import — everything exported from aquilia.models
from aquilia.models import (
    Window,
    Rank, DenseRank, RowNumber, Ntile,
    Lag, Lead, FirstValue, LastValue, NthValue,
    FrameType, FrameBound, WindowFrame,
    Sum, Avg, Count,   # aggregates work as window functions too
    F, OrderBy,
)

# Or import from the window module directly
from aquilia.models.window import Window, Rank, FrameBound, WindowFrame
```

```python
# Window generates: RANK() OVER (PARTITION BY "country" ORDER BY "score" DESC)
result = await User.objects.annotate(
    rank=Window(Rank(), partition_by=['country'], order_by='-score')
).all()

# Access annotation on each row:
for user in result:
    print(user.rank, user.name)  # 1 Alice, 2 Bob, ...
```

```python
from aquilia.models import Rank, DenseRank, RowNumber, Ntile, Window

# Leaderboard: rank players per game, ordered by score DESC
leaderboard = await PlayerScore.objects.annotate(
    rank=Window(Rank(), partition_by=['game_id'], order_by='-score'),
    dense_rank=Window(DenseRank(), partition_by=['game_id'], order_by='-score'),
    row_num=Window(RowNumber(), partition_by=['game_id'], order_by='-score'),
).order('game_id', 'rank').all()

# Percentile buckets: split each department into 4 salary quartiles
quartiles = await Employee.objects.annotate(
    quartile=Window(Ntile(4), partition_by=['department_id'], order_by='salary')
).all()
# quartile=1 → lowest 25%, quartile=4 → top 25%
```



---

## Common Table Expressions
**URL**: `https://tubox.cloud/docs/models/cte`

Docs / Models / Common Table Expressions Common Table Expressions Named subqueries defined at the start of a statement — compose readable, reusable query fragments. v1.3.3+ Concept A Common Table Expression (CTE) is a named, temporary result set defined with a WITH name AS (SELECT ...) clause that precedes the main query. The main query can then reference the CTE by name as if it were a table. CTEs excel at: Breaking complex queries into readable steps — each CTE is a named, focused subquery Reusing subquery results — reference the same CTE multiple times in the main query Post-processing window function results — filter on a windowed annotation (impossible in a single SELECT) Analytics pipelines — chain filtering, ranking, and aggregation as separate named stages Performance note: Most databases materialise CTEs once (PostgreSQL < 12 always; PostgreSQL 12+ optimises unless MATERIALIZED is specified). On SQLite and MySQL 8.0+, the optimiser may inline CTEs. Measure with .explain() if performance matters. Imports from aquilia.models import CTE, CTEReference, CTECol # CTE objects are also created via the QuerySet .cte() method — no direct instantiation needed Basic Non-Recursive CTE Call .cte(name) on any QuerySet to create a named CTE, then pass it to .with_cte() on the outer query. The outer query can then reference the CTE name as a table. from aquilia.models import F # Step 1: Define the CTE queryset active_users_qs = User.objects.filter(is_active=True, verified=True) # Step 2: Name it as a CTE active_users = active_users_qs.cte('active_users') # Step 3: Use it in an outer query # Note: the outer query selects FROM the CTE name as a table result = await ( User.objects .with_cte(active_users) .filter(role='admin') .order('-created_at') .all() ) # Generates: # WITH "active_users" AS ( # SELECT * FROM "users" WHERE "is_active" = ? AND "verified" = ? # ) # SELECT * FROM "users" WHERE "role" = ? ORDER BY "created_at" DESC Multiple CTEs Pass multiple CTEs to .with_cte() in a single call, or chain calls additively. CTEs are rendered in registration order. # Analytics pipeline: filter → annotate → join via CTEs # CTE 1: active users with post count active_qs = User.objects.filter(is_active=True) active = active_qs.cte('active_users') # CTE 2: top posts (last 30 days) from datetime import datetime, timedelta cutoff = datetime.utcnow() - timedelta(days=30) top_posts_qs = Post.objects.filter(created_at__gte=cutoff).order('-likes') top_posts = top_posts_qs.cte('recent_top_posts') # Main query referencing both result = await ( User.objects .with_cte(active, top_posts) # both CTEs in one call .filter(is_active=True) .all() ) # Generates: # WITH "active_users" AS (...), # "recent_top_posts" AS (...) # SELECT ... Referencing CTE Columns Use cte.col("column_name") to get a CTECol expression that renders as "cte_name"."column". Use this in filter expressions or annotations that reference the CTE. from aquilia.models import CTE, F ranked_qs = Post.objects.annotate( rn=Window(RowNumber(), partition_by=['author_id'], order_by='-likes') ) ranked = ranked_qs.cte('ranked_posts') # Reference CTE column in outer query filter top3_col = ranked.col('rn') # → CTECol("ranked_posts", "rn") # Use in annotation or raw filter result = await ( Post.objects .with_cte(ranked) .filter(** ) # Filter on annotated window rank from CTE .all() ) Production Pattern: Rank + Filter The most common CTE pattern is computing a window function annotation in a CTE and then filtering on it in the outer query — bypassing the SQL restriction that window functions cannot appear in WHERE. from aquilia.models import Window, RowNumber, F # TOP-3 POSTS PER AUTHOR — using CTE to filter on window annotation # Inner queryset: annotate with row number within each author's partition ranked_qs = Post.objects.annotate( rn=Window( RowNumber(), partition_by=['author_id'], order_by='-likes', ) ) ranked = ranked_qs.cte('ranked_posts') # Outer query: select from the CTE, filter on rn top3 = await ( Post.objects .with_cte(ranked) .filter(rn__lte=3) # Now valid — rn is a column in the CTE .order('author_id', 'rn') .all() ) # → Up to 3 most-liked posts per author Parameter Ordering Aquilia guarantees correct parameter ordering: CTE bind values are prepended before the main query's annotation params and WHERE params. You should not need to manage this manually. # The generated parameterized query: # WITH "active_users" AS (SELECT ... WHERE "is_active" = ?) ← CTE param: True # SELECT * FROM "users" WHERE "role" = ? ← WHERE param: 'admin' # Final params: [True, 'admin'] (CTE params first, always) Backend Compatibility Backend Min Version Notes ))} Window Functions Recursive CTEs );

### Code Examples
```python
from aquilia.models import CTE, CTEReference, CTECol
# CTE objects are also created via the QuerySet .cte() method — no direct instantiation needed
```

```python
from aquilia.models import F

# Step 1: Define the CTE queryset
active_users_qs = User.objects.filter(is_active=True, verified=True)

# Step 2: Name it as a CTE
active_users = active_users_qs.cte('active_users')

# Step 3: Use it in an outer query
# Note: the outer query selects FROM the CTE name as a table
result = await (
    User.objects
    .with_cte(active_users)
    .filter(role='admin')
    .order('-created_at')
    .all()
)

# Generates:
# WITH "active_users" AS (
#     SELECT * FROM "users" WHERE "is_active" = ? AND "verified" = ?
# )
# SELECT * FROM "users" WHERE "role" = ? ORDER BY "created_at" DESC
```

```python
# Analytics pipeline: filter → annotate → join via CTEs

# CTE 1: active users with post count
active_qs = User.objects.filter(is_active=True)
active = active_qs.cte('active_users')

# CTE 2: top posts (last 30 days)
from datetime import datetime, timedelta
cutoff = datetime.utcnow() - timedelta(days=30)
top_posts_qs = Post.objects.filter(created_at__gte=cutoff).order('-likes')
top_posts = top_posts_qs.cte('recent_top_posts')

# Main query referencing both
result = await (
    User.objects
    .with_cte(active, top_posts)   # both CTEs in one call
    .filter(is_active=True)
    .all()
)

# Generates:
# WITH "active_users" AS (...),
#      "recent_top_posts" AS (...)
# SELECT ...
```



---

## Recursive CTEs
**URL**: `https://tubox.cloud/docs/models/recursive-cte`

Docs / Models / Recursive CTEs Recursive CTEs Traverse hierarchical and graph data in pure SQL — folder trees, org charts, dependency graphs. v1.3.3+ Concept A recursive CTE uses the WITH RECURSIVE keyword and consists of two parts joined by UNION ALL (or UNION): Anchor term — the base query, run once, producing initial rows (e.g., root nodes) Recursive term — references the CTE itself to join against previous iteration results, expanding outward The database engine iterates until the recursive term produces no new rows. Warning: Without a termination condition, recursive CTEs can loop infinitely on cyclic graphs. Use UNION (not UNION ALL) to deduplicate and prevent cycles, or add a depth counter and filter it in the anchor or application layer. API: Q.recursive_cte() Parameter Type Description ))} .recursive_cte() returns a new QuerySet that selects FROM the named CTE table and carries the RecursiveCTE in its WITH RECURSIVE clause. Terminal methods (.all(), .first()) execute the full query. Example: Folder Tree Traversal A self-referential Folder model with a parent_id nullable FK to itself. class Folder(Model): table = "folders" name = CharField(max_length=255) parent_id = IntegerField(null=True) # FK to folders.id # Fetch entire subtree rooted at parent_id IS NULL (top-level) all_folders = await Folder.objects.recursive_cte( name='folder_tree', anchor=lambda q: q.filter(parent_id__isnull=True), # Root nodes recursive=lambda cte: Folder.objects.filter( parent_id=cte.col('id') # Children of previous level ), union_all=True, # Trees have no cycles — UNION ALL is faster ).all() # Generates: # WITH RECURSIVE "folder_tree" AS ( # SELECT * FROM "folders" WHERE "parent_id" IS NULL -- anchor # UNION ALL # SELECT f.* FROM "folders" f # INNER JOIN "folder_tree" ft ON f."parent_id" = ft."id" -- recursive # ) # SELECT * FROM "folder_tree" Example: Org Chart (All Reports Under a Manager) class Employee(Model): table = "employees" name = CharField(max_length=255) manager_id = IntegerField(null=True) # FK to employees.id async def all_reports(manager_id: int) -> list[Employee]: """Return the manager and all their direct/indirect reports.""" return await Employee.objects.recursive_cte( name='reports', anchor=lambda q: q.filter(id=manager_id), # Start node recursive=lambda cte: Employee.objects.filter( manager_id=cte.col('id') ), union_all=True, ).all() Example: Dependency Graph (UNION for Cycle Safety) class Package(Model): table = "packages" name = CharField(max_length=255) class PackageDep(Model): table = "package_deps" package_id = IntegerField() depends_on_id = IntegerField() # Resolve all transitive dependencies of a given package async def transitive_deps(package_id: int) -> list[Package]: return await Package.objects.recursive_cte( name='dep_tree', anchor=lambda q: q.filter(id=package_id), recursive=lambda cte: Package.objects.filter( packagedep__package_id=cte.col('id') ), union_all=False, # UNION — deduplicates, prevents infinite loops on diamond deps ).all() UNION vs UNION ALL Setting SQL When to use ))} CTEReference and cte.col() Inside the recursive lambda, the argument is a CTEReference. Call .col("column") on it to produce a CTECol expression that renders as "cte_name"."column" in SQL. lambda cte: Folder.objects.filter(parent_id=cte.col('id')) # cte.col('id') → CTECol("folder_tree", "id") # Renders as: "folders"."parent_id" = "folder_tree"."id" Performance Considerations ℹ Index parent_id — the recursive join hits parent_id on every iteration. Missing index causes full table scan per level. ℹ Depth-limit via counter — add a depth annotation in the anchor (initialized to 0 via Value(0)) and increment in the recursive term to limit traversal depth. ⚠ Large result sets — recursive CTEs materialize all levels before returning. For very deep trees, combine with .limit() or use a depth counter. ✓ Use .explain() — await Folder.objects.recursive_cte(...).explain() shows the query plan including CTE materialization strategy. Backend Compatibility Backend Min Version Notes ))} Common Table Expressions Bulk Operations );

### Code Examples
```python
class Folder(Model):
    table = "folders"
    name = CharField(max_length=255)
    parent_id = IntegerField(null=True)   # FK to folders.id

# Fetch entire subtree rooted at parent_id IS NULL (top-level)
all_folders = await Folder.objects.recursive_cte(
    name='folder_tree',
    anchor=lambda q: q.filter(parent_id__isnull=True),        # Root nodes
    recursive=lambda cte: Folder.objects.filter(
        parent_id=cte.col('id')                                # Children of previous level
    ),
    union_all=True,   # Trees have no cycles — UNION ALL is faster
).all()

# Generates:
# WITH RECURSIVE "folder_tree" AS (
#     SELECT * FROM "folders" WHERE "parent_id" IS NULL          -- anchor
#     UNION ALL
#     SELECT f.* FROM "folders" f
#     INNER JOIN "folder_tree" ft ON f."parent_id" = ft."id"     -- recursive
# )
# SELECT * FROM "folder_tree"
```

```python
class Employee(Model):
    table = "employees"
    name = CharField(max_length=255)
    manager_id = IntegerField(null=True)   # FK to employees.id

async def all_reports(manager_id: int) -> list[Employee]:
    """Return the manager and all their direct/indirect reports."""
    return await Employee.objects.recursive_cte(
        name='reports',
        anchor=lambda q: q.filter(id=manager_id),         # Start node
        recursive=lambda cte: Employee.objects.filter(
            manager_id=cte.col('id')
        ),
        union_all=True,
    ).all()
```

```python
class Package(Model):
    table = "packages"
    name = CharField(max_length=255)

class PackageDep(Model):
    table = "package_deps"
    package_id = IntegerField()
    depends_on_id = IntegerField()

# Resolve all transitive dependencies of a given package
async def transitive_deps(package_id: int) -> list[Package]:
    return await Package.objects.recursive_cte(
        name='dep_tree',
        anchor=lambda q: q.filter(id=package_id),
        recursive=lambda cte: Package.objects.filter(
            packagedep__package_id=cte.col('id')
        ),
        union_all=False,   # UNION — deduplicates, prevents infinite loops on diamond deps
    ).all()
```



---

## Bulk Operations
**URL**: `https://tubox.cloud/docs/models/bulk-operations`

Docs / Models / Bulk Operations Bulk Operations Efficient batch INSERT, bulk UPDATE, bulk DELETE, chunked iteration, and upsert patterns. Signal behavior: bulk_create(), .update(), and .delete() do not fire pre_save, post_save, pre_delete, or post_delete signals. They operate directly at the SQL layer. Use instance-level .save() / .delete_instance() when signals are required. bulk_create() Inserts a list of model instances in one or more batched INSERT statements. Dramatically faster than calling .save() per instance for large datasets. # Signature async def bulk_create( db: AquiliaDatabase, objs: list[Model], batch_size: int = 1000, ) -> None # Example: import 50,000 products products = [ Product(name=row['name'], price=row['price'], sku=row['sku']) for row in csv_rows ] await Product.objects.bulk_create(db, products, batch_size=500) # → Executes 100 INSERT statements, 500 rows each # After bulk_create, PKs may or may not be assigned depending on backend. # Re-query if you need the assigned IDs: created = await Product.objects.filter(sku__in=[p.sku for p in products]).all() batch_size guidance: SQLite has a default variable limit of 999 per statement. Keep batch_size at or below 999 for SQLite. PostgreSQL handles much larger batches efficiently. MySQL performs well at 500–5000 rows per batch depending on row width. .update() — Bulk UPDATE Issues a single UPDATE ... SET ... WHERE ... statement for all rows matching the queryset filter. Accepts literal values, F() expressions, arithmetic, and Case() expressions. # Signature async def update(self, db: AquiliaDatabase, **kwargs) -> int # returns rows affected # Literal update — set all active users' role to 'member' count = await User.objects.filter(is_active=True).update(db, role='member') # F() expression — atomic increment (no Python read-modify-write) await Product.objects.filter(id__in=popular_ids).update(db, views=F('views') + 1) # Arithmetic on multiple fields await Order.objects.filter(status='pending').update( db, total=F('subtotal') + F('tax'), updated_at=Now(), ) # Conditional update with Case/When from aquilia.models.expression import Case, When, Value await Product.objects.update( db, status=Case( When(stock=0, then=Value('out_of_stock')), When(stock__lt=10, then=Value('low_stock')), default=Value('in_stock'), ) ) # Limit scope with filter affected = await User.objects.filter( last_login__lt=cutoff_date ).update(db, is_active=False) .delete() — Bulk DELETE Issues a single DELETE FROM ... WHERE ... for all rows matching the queryset. No signals fire. # Signature async def delete(self, db: AquiliaDatabase) -> int # returns rows deleted # Delete all expired sessions deleted = await Session.objects.filter(expires_at__lt=now).delete(db) # Delete with complex filter await Log.objects.filter( created_at__lt=cutoff, level__in=['DEBUG', 'INFO'], ).delete(db) # WARNING: .delete() with no filter deletes ALL rows in the table. # Always verify your filter scope before calling .delete(). in_bulk() Fetches a list of PKs and returns a dict mapping each PK to its model instance. Internally chunks large lists to avoid hitting SQLite's variable limit. # Signature async def in_bulk( self, id_list: list, batch_size: int = 999, ) -> dict[Any, Model] # Fetch multiple users by ID without N+1 user_ids = [1, 5, 42, 99] user_map = await User.objects.in_bulk(db, user_ids) # → alice = user_map[1] # Large ID list — automatically chunked into batches of 999 all_ids = list(range(1, 50001)) product_map = await Product.objects.in_bulk(db, all_ids) # → Makes ceil(50000/999) queries, merges results into one dict Upsert Patterns Aquilia provides three methods for common get-or-create / upsert patterns. Understand their guarantees before choosing: Method Creates? Updates? Race-safe? ))} RuntimeWarning: get_or_create() and update_or_create() emit a RuntimeWarning on every call, since both are a plain SELECT-then-INSERT/UPDATE and not atomic under concurrent access. Prefer find_or_create() when a unique constraint is available — it does not warn. get_or_create() # Returns (instance, created: bool) user, created = await User.objects.get_or_create( db, defaults= , email='alice@example.com', # lookup fields ) if created: print("New user created") else: print("Existing user fetched") update_or_create() # Returns (instance, created: bool) # Updates existing row with defaults fields, or creates new row profile, created = await Profile.objects.update_or_create( db, defaults= , user_id=42, # lookup key ) find_or_create() — Atomic Upsert Uses INSERT ... ON CONFLICT DO NOTHING under the hood, eliminating the TOCTOU race condition present in get_or_create. Safe under concurrent load without transactions. # Returns (instance, created: bool) tag, created = await Tag.objects.find_or_create( db, defaults= , create_defaults= , name='Python', # lookup + unique constraint field ) # Under the hood: # INSERT INTO "tags" ("name", "color", "slug") # VALUES (?, ?, ?) ON CONFLICT DO NOTHING # Then SELECT to return the row regardless of insert vs conflict .iterator() — Memory-Efficient Chunked Iteration .iterator() returns an async generator that fetches and yields rows in chunks. Unlike .all(), it does not load the entire result set into memory at once — essential for processing hundreds of thousands of rows. # Signature def iterator(self, chunk_size: int = 2000) -> AsyncGenerator[Model, None] # Process 1M rows without OOM async for user in User.objects.filter(is_active=True).iterator(chunk_size=500): await process_user(user) # With ordering — ensures consistent chunking async for order in Order.objects.order('id').iterator(): await send_receipt(order) # Cannot use .all() or .first() after .iterator() — it is a terminal method # Cannot slice or further chain after calling .iterator() select_for_update() Adds SELECT ... FOR UPDATE locking to the query. Must be used inside an atomic() block. Not supported on SQLite (raises QueryFault on SQLite). # Signature def select_for_update( self, nowait: bool = False, skip_locked: bool = False, ) -> QuerySet from aquilia.models import atomic async with atomic(db): # Lock the row for the duration of the transaction account = await ( BankAccount.objects .filter(id=account_id) .select_for_update() .first() ) account.balance -= amount await account.save(db) # nowait=True → raises immediately if row is locked (no waiting) async with atomic(db): try: job = await Job.objects.filter(status='pending').select_for_update(nowait=True).first() except Exception: return # Another worker has it # skip_locked=True → skips locked rows (queue worker pattern) async with atomic(db): job = await ( Job.objects .filter(status='pending') .select_for_update(skip_locked=True) .order('created_at') .first() ) if job: await process_job(job) Recursive CTEs Advanced Usage );

### Code Examples
```python
# Signature
async def bulk_create(
    db: AquiliaDatabase,
    objs: list[Model],
    batch_size: int = 1000,
) -> None

# Example: import 50,000 products
products = [
    Product(name=row['name'], price=row['price'], sku=row['sku'])
    for row in csv_rows
]
await Product.objects.bulk_create(db, products, batch_size=500)
# → Executes 100 INSERT statements, 500 rows each

# After bulk_create, PKs may or may not be assigned depending on backend.
# Re-query if you need the assigned IDs:
created = await Product.objects.filter(sku__in=[p.sku for p in products]).all()
```

```python
# Signature
async def update(self, db: AquiliaDatabase, **kwargs) -> int  # returns rows affected

# Literal update — set all active users' role to 'member'
count = await User.objects.filter(is_active=True).update(db, role='member')

# F() expression — atomic increment (no Python read-modify-write)
await Product.objects.filter(id__in=popular_ids).update(db, views=F('views') + 1)

# Arithmetic on multiple fields
await Order.objects.filter(status='pending').update(
    db,
    total=F('subtotal') + F('tax'),
    updated_at=Now(),
)

# Conditional update with Case/When
from aquilia.models.expression import Case, When, Value
await Product.objects.update(
    db,
    status=Case(
        When(stock=0, then=Value('out_of_stock')),
        When(stock__lt=10, then=Value('low_stock')),
        default=Value('in_stock'),
    )
)

# Limit scope with filter
affected = await User.objects.filter(
    last_login__lt=cutoff_date
).update(db, is_active=False)
```

```python
# Signature
async def delete(self, db: AquiliaDatabase) -> int  # returns rows deleted

# Delete all expired sessions
deleted = await Session.objects.filter(expires_at__lt=now).delete(db)

# Delete with complex filter
await Log.objects.filter(
    created_at__lt=cutoff,
    level__in=['DEBUG', 'INFO'],
).delete(db)

# WARNING: .delete() with no filter deletes ALL rows in the table.
# Always verify your filter scope before calling .delete().
```



---

## Contracts
**URL**: `https://tubox.cloud/docs/contracts`

const stages = [ , , , , , ] function ContractArchitectureVisualizer( : ) , seal: , imprint: , projection: , lens: , mold: }; const activeStep = hoveredStep ? stepsData[hoveredStep as keyof typeof stepsData] : null; return ( System Architecture Dual-track request-response lifecycle loops through the central Contract contract. CONTRACT MODEL REQUEST RESPONSE setHoveredStep('cast')} onMouseLeave= > 1. CAST setHoveredStep('seal')} onMouseLeave= > 2. SEAL setHoveredStep('imprint')} onMouseLeave= > 3. IMPRINT setHoveredStep('projection')} onMouseLeave= > 1. PROJECT setHoveredStep('lens')} onMouseLeave= > 2. LENS setHoveredStep('mold')} onMouseLeave= > 3. MOLD ) : ( Hover over any numbered node in the pipeline curve to view its execution specifications. )} Inbound Pipeline (Request Data) 1. Cast Phase Coerces input dictionaries into target Python types via individual Facet casting pipelines. 2. Seal Phase Runs facet constraint validators and sweeps custom @ward cross-field integrity checks. 3. Imprint Phase Flushes valid datasets back into the ORM models to trigger SQL inserts or updates. Outbound Pipeline (Response Model) 1. Projection Selection Filters attributes based on named projection limits, respecting write-only properties. 2. Lens Resolution Fetches related data through nested Lens paths, enforcing recursion and cycle limits. 3. Mold Phase Serializes model elements to standard native dictionaries for JSON serialization. ); } Docs / Contracts Contracts Contract is Aquilia's first-class model↔world contract. Not a serializer — a typed framework primitive that handles inbound validation, outbound serialization, and model persistence in one cohesive API. Evolution in V1.3.0 Blueprint is now Contract We've renamed our core model-world data primitive. The semantics are unchanged, but the naming now perfectly reflects its behavior: a formal, bidirectional contract between models and the outside world. Legacy (Pre v1.3) Blueprint Represented schemas as static templates. Required importing Blueprint, BlueprintMeta, and defining class Spec. Current (v1.3+) Contract Expresses data validation, persistence, and serialization as a formal business agreement. Clearer APIs and unified imports. Contract ≠ Serializer A Contract declares what the world sees ( Facets ), named subsets ( Projections ), how data enters (Casts), integrity rules ( @ward Seals), and how data writes back ( imprint() ). A single class covers the full request/response lifecycle. Lifecycle ))} Quick Start from aquilia.contracts import Contract, TextFacet, IntFacet, EmailFacet, DateTimeFacet, Computed from aquilia.contracts.annotations import computed class UserContract(Contract): # Explicit Facets name = TextFacet(max_length=150, min_length=1) email = EmailFacet() bio = TextFacet(max_length=500, required=False, default="") # Computed read-only field @computed def display_name(self) -> str: return self.instance.name.title() if self.instance else "" class Spec: model = User projections = read_only_fields = ("id", "display_name") write_only_fields = ("password",) depth = 2 Outbound — Model → Dict Pass instance= to serialize. Apply a projection with projection= or the subscript syntax: user = await User.objects.get(id=42) # All fields (or default_projection) data = UserContract(instance=user).data # Named projection data = UserContract(instance=user, projection="public").data # Subscript syntax (used with route decorators) data = UserContract["public"](instance=user).data # List of instances users = await User.objects.filter(active=True).all() result = [UserContract(instance=u, projection="public").data for u in users] Inbound — Validate + Persist Pass data= to validate. Call is_sealed() to run all Facet validators and @ward methods. If valid, call imprint() to write back. bp = UserContract(data=request.json) if not bp.is_sealed(): return Response.json( , status=422) user = await bp.imprint(db=db) # INSERT into users table return Response.json(UserContract(instance=user, projection="profile").data, status=201) Update an existing instance by passing it to imprint(): user = await User.objects.get(id=42) bp = UserContract(data=request.json) if not bp.is_sealed(): return Response.json( , status=422) user = await bp.imprint(db=db, instance=user) # UPDATE users SET ... return Response.json(UserContract(instance=user).data) Route Integration Contracts integrate directly with route decorators via request_contract and response_contract : from aquilia.controllers import GET, POST, PUT from aquilia.db import get_database @GET("/users", response_contract=UserContract["public"]) async def list_users(ctx): return await User.objects.filter(active=True).all() # Aquilia auto-serializes each User via UserContract["public"] @POST("/users", request_contract=UserContract, response_contract=UserContract["profile"]) async def create_user(ctx, contract: UserContract): if not contract.is_sealed(): return Response.json(contract.errors, status=422) user = await contract.imprint(db=get_database()) return user # auto-serialized via response_contract @PUT("/users/ ", request_contract=UserContract, response_contract=UserContract["profile"]) async def update_user(ctx, contract: UserContract, id: int): user = await User.objects.get(id=id) if not contract.is_sealed(): return Response.json(contract.errors, status=422) return await contract.imprint(db=get_database(), instance=user) Annotation-Driven Declarations Use Python type annotations with Field() descriptors instead of explicit Facet classes. Aquilia auto-derives the correct Facet from the type: from aquilia.contracts import Contract from aquilia.contracts.annotations import Field, computed class ProductContract(Contract): name: str = Field(min_length=1, max_length=200) price: float = Field(ge=0.0) sku: str = Field(pattern=r"^[A-Z0-9-]+$", max_length=50) tags: list[str] = Field(default_factory=list, max_items=20) active: bool = Field(default=True) notes: str | None = None # Optional field, no constraints @computed def price_display(self) -> str: return f"\\\\\$ " if self.instance else "" class Spec: model = Product Explore , , , , , , ].map(( ) => ( ))} )

### Code Examples
```python
from aquilia.contracts import Contract, TextFacet, IntFacet, EmailFacet, DateTimeFacet, Computed
from aquilia.contracts.annotations import computed

class UserContract(Contract):
    # Explicit Facets
    name     = TextFacet(max_length=150, min_length=1)
    email    = EmailFacet()
    bio      = TextFacet(max_length=500, required=False, default="")

    # Computed read-only field
    @computed
    def display_name(self) -> str:
        return self.instance.name.title() if self.instance else ""

    class Spec:
        model = User
        projections = {
            "public":   ["id", "name", "display_name"],
            "profile":  ["id", "name", "email", "bio", "display_name"],
            "admin":    "__all__",
        }
        read_only_fields  = ("id", "display_name")
        write_only_fields = ("password",)
        depth = 2
```

```python
user = await User.objects.get(id=42)

# All fields (or default_projection)
data = UserContract(instance=user).data

# Named projection
data = UserContract(instance=user, projection="public").data

# Subscript syntax (used with route decorators)
data = UserContract["public"](instance=user).data

# List of instances
users = await User.objects.filter(active=True).all()
result = [UserContract(instance=u, projection="public").data for u in users]
```

```python
bp = UserContract(data=request.json)

if not bp.is_sealed():
    return Response.json({"errors": bp.errors}, status=422)

user = await bp.imprint(db=db)   # INSERT into users table
return Response.json(UserContract(instance=user, projection="profile").data, status=201)
```



---

## Facets
**URL**: `https://tubox.cloud/docs/contracts/facets`

Docs / Contracts / Facets Facets Atomic field-level primitives of a Contract contract. Each Facet manages type coercion (cast), validation (seal), and output representation (mold). Base Facet Options from aquilia.contracts import Facet field = Facet( source="model_field", # read from distinct model attribute required=True, # fail CastFault if missing on inbound read_only=False, # exclude from inbound cast write_only=False, # exclude from outbound serialization default=None, # fallback value allow_null=False, # accept None allow_blank=False, # accept empty string (TextFacet only) validators=[], # additional validator callables ) Built-in Facets TextFacet Handles string properties with length boundaries and pattern matching. sku = TextFacet(max_length=50, pattern=r"^[A-Z0-9-]+$") IntFacet Coerces numeric strings/floats to integers. Validates min_value and max_value. Rejects booleans. quantity = IntFacet(min_value=1, max_value=99) Computed Derived read-only fields computed via a function or method. Can also use the @computed decorator. # Inline lambda computed facet full_name = Computed(lambda bp: f" ") # Method decorator pattern @computed def display_title(self) -> str: return self.instance.title.upper() Choice Constraint Restricts values to a specific set. Supports lists, dicts, or tuples: from aquilia.contracts import ChoiceFacet # List choices status = ChoiceFacet(choices=["draft", "published"]) # Dict choices (value -> description) priority = ChoiceFacet(choices= ) Facet Registry Reference Facet Python Target Description ))} Overview Projections )

### Code Examples
```python
from aquilia.contracts import Facet

field = Facet(
    source="model_field",     # read from distinct model attribute
    required=True,            # fail CastFault if missing on inbound
    read_only=False,          # exclude from inbound cast
    write_only=False,         # exclude from outbound serialization
    default=None,             # fallback value
    allow_null=False,         # accept None
    allow_blank=False,        # accept empty string (TextFacet only)
    validators=[],            # additional validator callables
)
```

```python
sku = TextFacet(max_length=50, pattern=r"^[A-Z0-9-]+$")
```

```python
quantity = IntFacet(min_value=1, max_value=99)
```



---

## Projections
**URL**: `https://tubox.cloud/docs/contracts/projections`

Contracts / Projections Projections Projections let you define named subsets of fields within a single Contract. Instead of creating separate Contracts for list views vs detail views vs admin views, you declare projections and select them at render time. Why Projections? , , , , ].map((item, i) => ( ))} Defining Projections Projections are declared in the Spec inner class as a dictionary mapping names to field lists. from aquilia.contracts import Contract, TextFacet, EmailFacet, FloatFacet, Computed, Lens class ProductContract(Contract): name = TextFacet(max_length=200) slug = TextFacet(max_length=100) price = FloatFacet() description = TextFacet(max_length=5000) internal_notes = TextFacet(max_length=2000) category = TextFacet() sku = TextFacet() stock_count = IntFacet() is_active = BoolFacet() created_at = DateTimeFacet(read_only=True) reviews = Lens("ReviewContract", many=True) # Computed field display_price = Computed(lambda inst: "$%.2f" % inst.price) class Spec: model = Product fields = "__all__" read_only_fields = ["id", "created_at"] # Projection definitions projections = # Default projection when none specified default_projection = "summary" Special Projection Names Name Meaning , , , , ].map((row, i) => ( ))} Using Projections product = await Product.objects.get(id=1) # Use default projection ("summary") data = ProductContract(instance=product).data # # Use minimal projection data = ProductContract(instance=product, projection="__minimal__").data # # Use detail projection (excludes internal_notes, stock_count) data = ProductContract(instance=product, projection="detail").data # Use admin projection (all fields) data = ProductContract(instance=product, projection="__all__").data # Serialize many instances with projection products = await Product.objects.all() data = ProductContract(instance=products, many=True, projection="__minimal__").data Projections in Controllers from aquilia import Controller, Get class ProductController(Controller): prefix = "/api/products" @Get("/") async def list_products(self, ctx): products = await Product.objects.all() # Minimal projection for list views — fast, small payload return ctx.json( ProductContract(instance=products, many=True, projection="__minimal__").data ) @Get("/ ") async def detail(self, ctx, id: int): product = await Product.objects.get(id=id) # Full detail projection return ctx.json( ProductContract(instance=product, projection="detail").data ) @Get("/ /admin") async def admin_detail(self, ctx, id: int): product = await Product.objects.get(id=id) # Admin sees everything return ctx.json( ProductContract(instance=product, projection="__all__").data ) Subscript Syntax for Lenses When using Lens facets, you can select which projection the nested Contract uses via Python's subscript syntax: from aquilia.contracts import Contract, Lens class OrderContract(Contract): # Render products with their "summary" projection items = Lens(ProductContract["summary"], many=True) # Render customer with "public" projection customer = Lens(CustomerContract["public"]) class Spec: model = Order fields = "__all__" # This is shorthand for: # items = Lens(ProductContract, many=True, projection="summary") ProjectionRegistry API # Inspect available projections print(ProductContract._projections.available) # ["__minimal__", "summary", "detail", "__all__", "public"] # Get default projection name print(ProductContract._projections.default_name) # "summary" # Resolve a projection to field names fields = ProductContract._projections.resolve("__minimal__") # ["id", "name", "price", "slug"] # Resolve exclusion projection fields = ProductContract._projections.resolve("detail") # All fields except "internal_notes" and "stock_count" )

### Code Examples
```python
from aquilia.contracts import Contract, TextFacet, EmailFacet, FloatFacet, Computed, Lens


class ProductContract(Contract):
    name = TextFacet(max_length=200)
    slug = TextFacet(max_length=100)
    price = FloatFacet()
    description = TextFacet(max_length=5000)
    internal_notes = TextFacet(max_length=2000)
    category = TextFacet()
    sku = TextFacet()
    stock_count = IntFacet()
    is_active = BoolFacet()
    created_at = DateTimeFacet(read_only=True)
    reviews = Lens("ReviewContract", many=True)
    
    # Computed field
    display_price = Computed(lambda inst: "$%.2f" % inst.price)

    class Spec:
        model = Product
        fields = "__all__"
        read_only_fields = ["id", "created_at"]
        
        # Projection definitions
        projections = {
            # Minimal fields for list/search views
            "__minimal__": ["id", "name", "price", "slug"],
            
            # Summary for card displays
            "summary": ["id", "name", "price", "category", "display_price", "is_active"],
            
            # Full detail view (excludes internal data)
            "detail": ["-internal_notes", "-stock_count"],
            
            # Admin view — everything
            "__all__": "__all__",
            
            # Public view — explicitly listed fields
            "public": ["id", "name", "price", "description", "category", "reviews"],
        }
        
        # Default projection when none specified
        default_projection = "summary"
```

```python
product = await Product.objects.get(id=1)

# Use default projection ("summary")
data = ProductContract(instance=product).data
# {"id": 1, "name": "Widget", "price": 9.99, "category": "electronics", ...}

# Use minimal projection
data = ProductContract(instance=product, projection="__minimal__").data
# {"id": 1, "name": "Widget", "price": 9.99, "slug": "widget"}

# Use detail projection (excludes internal_notes, stock_count)
data = ProductContract(instance=product, projection="detail").data

# Use admin projection (all fields)
data = ProductContract(instance=product, projection="__all__").data

# Serialize many instances with projection
products = await Product.objects.all()
data = ProductContract(instance=products, many=True, projection="__minimal__").data
```

```python
from aquilia import Controller, Get


class ProductController(Controller):
    prefix = "/api/products"

    @Get("/")
    async def list_products(self, ctx):
        products = await Product.objects.all()
        # Minimal projection for list views — fast, small payload
        return ctx.json(
            ProductContract(instance=products, many=True, projection="__minimal__").data
        )

    @Get("/{id:int}")
    async def detail(self, ctx, id: int):
        product = await Product.objects.get(id=id)
        # Full detail projection
        return ctx.json(
            ProductContract(instance=product, projection="detail").data
        )

    @Get("/{id:int}/admin")
    async def admin_detail(self, ctx, id: int):
        product = await Product.objects.get(id=id)
        # Admin sees everything
        return ctx.json(
            ProductContract(instance=product, projection="__all__").data
        )
```



---

## Lenses
**URL**: `https://tubox.cloud/docs/contracts/lenses`

Contracts / Lenses Lenses Lenses are a special Facet type that renders related objects through another Contract. They provide depth-controlled, cycle-safe relational views — eliminating the need for manual nested serialization or N+1 query problems in your API responses. Core Concept A Lens is a Facet that delegates serialization to another Contract. When the parent Contract renders, each Lens field creates an instance of the target Contract and renders the related object through it. , , , ].map((item, i) => ( ))} Basic Usage from aquilia.contracts import Contract, TextFacet, IntFacet, Lens class CategoryContract(Contract): name = TextFacet(max_length=100) slug = TextFacet(max_length=100) class Spec: model = Category fields = ["id", "name", "slug"] class ReviewContract(Contract): rating = IntFacet(min_value=1, max_value=5) comment = TextFacet(max_length=500) author = TextFacet(source="author.username", read_only=True) class Spec: model = Review fields = ["id", "rating", "comment", "author"] class ProductContract(Contract): name = TextFacet(max_length=200) price = FloatFacet() # Single related object (ForeignKey) category = Lens(CategoryContract) # Multiple related objects (reverse FK / M2M) reviews = Lens(ReviewContract, many=True) class Spec: model = Product fields = "__all__" # Output: # , # "reviews": [ # , # , # ] # } Depth Control Lenses track nesting depth. When maximum depth is reached, the Lens falls back to rendering the primary key instead of the full nested object. # Default max_depth is 3 category = Lens(CategoryContract, max_depth=2) # At depth 0: Full nested object # At depth 1: Full nested object (still within limit) # At depth 2: Primary key only 5 (max_depth reached) # Custom depth for deep hierarchies comments = Lens(CommentContract, many=True, max_depth=5) # Example: Category with subcategories class CategoryContract(Contract): name = TextFacet() # Self-referential lens with depth control subcategories = Lens("CategoryContract", many=True, max_depth=3) parent = Lens("CategoryContract", max_depth=1) class Spec: model = Category fields = ["id", "name", "subcategories", "parent"] # Depth 0: ← PKs at max depth # ]} # ]} Cycle Detection If Contract A references Contract B which references Contract A, Aquilia detects this cycle and raises LensCycleFault instead of producing infinite recursion. class AuthorContract(Contract): name = TextFacet() books = Lens("BookContract", many=True) # Forward reference class Spec: model = Author fields = ["id", "name", "books"] class BookContract(Contract): title = TextFacet() author = Lens(AuthorContract) # Circular reference! class Spec: model = Book fields = ["id", "title", "author"] # Rendering: # AuthorContract renders → books → BookContract → author → AuthorContract # At this point, cycle is detected and rendering stops with PK fallback. # No LensCycleFault unless max_depth is also exceeded. # If you want to catch cycles explicitly: from aquilia.contracts.exceptions import LensCycleFault try: data = AuthorContract(instance=author).data except LensCycleFault as e: print(e.contract_chain) # ["AuthorContract", "BookContract", "AuthorContract"] Projection Selection with Subscript Syntax Use Python's subscript syntax Contract["projection"] to control which projection the nested Contract uses: class OrderContract(Contract): # Products rendered with minimal fields (fast list) items = Lens(ProductContract["__minimal__"], many=True) # Customer rendered with public-safe fields customer = Lens(CustomerContract["public"]) # Shipping address with full detail address = Lens(AddressContract["detail"]) class Spec: model = Order fields = "__all__" # Output: # , ← minimal # , ← minimal # ], # "customer": , ← public # "address": ← detail # } Forward References (Lazy Resolution) When Contract classes reference each other, use string names for forward references. They resolve lazily from the global Contract registry: class AuthorContract(Contract): name = TextFacet() # Forward reference — BookContract hasn't been defined yet books = Lens("BookContract", many=True) class Spec: model = Author fields = ["id", "name", "books"] # BookContract defined later class BookContract(Contract): title = TextFacet() author = Lens(AuthorContract) # Direct reference (already defined) class Spec: model = Book fields = ["id", "title", "author"] # Both work: # Lens(AuthorContract) — Direct class reference # Lens("AuthorContract") — String forward reference # Lens("BookContract") — Resolved from _contract_registry Lens Behavior on Input On inbound (input) data, Lenses accept the primary key value rather than nested objects. This prevents clients from arbitrarily modifying related objects through the parent: # Input payload for creating an order: } # If you want nested write support, use NestedContractFacet # from aquilia.contracts.annotations instead of Lens )

### Code Examples
```python
from aquilia.contracts import Contract, TextFacet, IntFacet, Lens


class CategoryContract(Contract):
    name = TextFacet(max_length=100)
    slug = TextFacet(max_length=100)

    class Spec:
        model = Category
        fields = ["id", "name", "slug"]


class ReviewContract(Contract):
    rating = IntFacet(min_value=1, max_value=5)
    comment = TextFacet(max_length=500)
    author = TextFacet(source="author.username", read_only=True)

    class Spec:
        model = Review
        fields = ["id", "rating", "comment", "author"]


class ProductContract(Contract):
    name = TextFacet(max_length=200)
    price = FloatFacet()

    # Single related object (ForeignKey)
    category = Lens(CategoryContract)

    # Multiple related objects (reverse FK / M2M)
    reviews = Lens(ReviewContract, many=True)

    class Spec:
        model = Product
        fields = "__all__"


# Output:
# {
#   "id": 1,
#   "name": "Widget",
#   "price": 9.99,
#   "category": {
#     "id": 5,
#     "name": "Electronics",
#     "slug": "electronics"
#   },
#   "reviews": [
#     {"id": 10, "rating": 5, "comment": "Great!", "author": "alice"},
#     {"id": 11, "rating": 4, "comment": "Good", "author": "bob"},
#   ]
# }
```

```python
# Default max_depth is 3
category = Lens(CategoryContract, max_depth=2)

# At depth 0: Full nested object   {"id": 5, "name": "Electronics", "slug": "..."}
# At depth 1: Full nested object   (still within limit)
# At depth 2: Primary key only     5  (max_depth reached)

# Custom depth for deep hierarchies
comments = Lens(CommentContract, many=True, max_depth=5)


# Example: Category with subcategories
class CategoryContract(Contract):
    name = TextFacet()
    
    # Self-referential lens with depth control
    subcategories = Lens("CategoryContract", many=True, max_depth=3)
    parent = Lens("CategoryContract", max_depth=1)

    class Spec:
        model = Category
        fields = ["id", "name", "subcategories", "parent"]

# Depth 0: {"id": 1, "name": "Root", "subcategories": [
#   {"id": 2, "name": "Child", "subcategories": [
#     {"id": 3, "name": "Grandchild", "subcategories": [4, 5]}  ← PKs at max depth
#   ]}
# ]}
```

```python
class AuthorContract(Contract):
    name = TextFacet()
    books = Lens("BookContract", many=True)  # Forward reference

    class Spec:
        model = Author
        fields = ["id", "name", "books"]


class BookContract(Contract):
    title = TextFacet()
    author = Lens(AuthorContract)  # Circular reference!

    class Spec:
        model = Book
        fields = ["id", "title", "author"]


# Rendering:
# AuthorContract renders → books → BookContract → author → AuthorContract
# At this point, cycle is detected and rendering stops with PK fallback.
# No LensCycleFault unless max_depth is also exceeded.

# If you want to catch cycles explicitly:
from aquilia.contracts.exceptions import LensCycleFault

try:
    data = AuthorContract(instance=author).data
except LensCycleFault as e:
    print(e.contract_chain)  # ["AuthorContract", "BookContract", "AuthorContract"]
```



---

## Seals & Validation
**URL**: `https://tubox.cloud/docs/contracts/seals`

Docs / Contracts / Seals & Validation Seals & Validation Sealing is validation. The is_sealed() method runs type checks, constraint enforcement, and custom @ward validators. Validation Pipeline , , , , ].map(p => ( ))} Execution # Instantiate with request body bp = ProductContract(data=request.json) # Run validations if not bp.is_sealed(): return Response.json(bp.errors, status=422) # Persist product = await bp.imprint(db=db) Cross-Field Validation Use the @ward decorator to enforce dependencies between multiple fields: from aquilia.contracts import Contract, SealFault from aquilia.contracts.ward import ward class EventContract(Contract): start_date = DateFacet() end_date = DateFacet() @ward def validate_dates(self): """Ensure end_date is strictly after start_date.""" start = self.validated.get("start_date") end = self.validated.get("end_date") if start and end and end Accumulating Errors Accumulate validation errors instead of raising immediately using self.reject(): {`class SignupContract(Contract): password = TextFacet(min_length=8) password_confirm = TextFacet() @ward def verify_password_match(self): pwd = self.validated.get("password") conf = self.validated.get("password_confirm") if pwd != conf: self.reject("password_confirm", "Passwords do not match.") Facets Projections )

### Code Examples
```python
# Instantiate with request body
bp = ProductContract(data=request.json)

# Run validations
if not bp.is_sealed():
    return Response.json(bp.errors, status=422)

# Persist
product = await bp.imprint(db=db)
```

```python
from aquilia.contracts import Contract, SealFault
from aquilia.contracts.ward import ward

class EventContract(Contract):
    start_date = DateFacet()
    end_date = DateFacet()

    @ward
    def validate_dates(self):
        """Ensure end_date is strictly after start_date."""
        start = self.validated.get("start_date")
        end = self.validated.get("end_date")
        if start and end and end <= start:
            # Raise SealFault to register field error
            raise SealFault({"end_date": "End date must be after start date"})
```

```python
class SignupContract(Contract):
    password = TextFacet(min_length=8)
    password_confirm = TextFacet()

    @ward
    def verify_password_match(self):
        pwd = self.validated.get("password")
        conf = self.validated.get("password_confirm")
        if pwd != conf:
            self.reject("password_confirm", "Passwords do not match.")
```



---

## Annotations & Field()
**URL**: `https://tubox.cloud/docs/contracts/annotations`

Contracts / Annotations & Field() Annotations & Field() As an alternative to explicit Facet declarations, Aquilia supports type-annotation-driven Contracts using the Field descriptor. Write Pythonic type hints and let the metaclass derive the correct Facets automatically. Two Declaration Styles Explicit Facets Full control, more verbose class UserBP(Contract): name = TextFacet(max_length=100) age = IntFacet(min_value=0) email = EmailFacet() Type Annotations Pythonic, concise, auto-derived class UserBP(Contract): name: str = Field(max_length=100) age: int = Field(ge=0) email: str = Field() Both styles produce identical Contract behavior. You can even mix them in the same Contract — explicit Facets take priority over annotation-derived ones. The Field() Descriptor Field is a constraint descriptor that decorates type annotations with validation rules: from aquilia.contracts import Contract, Field class ProductContract(Contract): # All Field() options: name: str = Field( default=None, # Default value if not provided required=True, # Is this field required in input? read_only=False, # Exclude from input, include in output write_only=False, # Include in input, exclude from output allow_null=False, # Allow None values # Numeric constraints (maps to min_value/max_value) ge=0, # Greater than or equal to le=100, # Less than or equal to gt=None, # Greater than (strict) lt=None, # Less than (strict) # String constraints min_length=None, # Minimum string length max_length=200, # Maximum string length pattern=None, # Regex pattern # Collection constraints min_items=None, # Minimum list items max_items=None, # Maximum list items # Choice constraint choices=None, # Allowed values (list/dict/tuple) # Decimal constraints max_digits=None, # Total digits (DecimalFacet) decimal_places=None, # Decimal places (DecimalFacet) # Source mapping alias=None, # Alternative name in input JSON ) class Spec: model = Product fields = "__all__" Type → Facet Mapping The introspect_annotations() system maps Python type annotations to the appropriate Facet class: Type Annotation Derived Facet , , , , , , , , , , , , , , , , , , , ].map((row, i) => ( ))} Practical Examples User Registration from aquilia.contracts import Contract, Field from datetime import date class RegisterContract(Contract): username: str = Field(min_length=3, max_length=30) email: str = Field(required=True) # Becomes EmailFacet? No — str → TextFacet password: str = Field(min_length=8, write_only=True) birth_date: date = Field(required=False) age: int = Field(ge=13, le=120, required=False) class Spec: model = User fields = ["username", "email", "password", "birth_date"] E-Commerce Order from aquilia.contracts import Contract, Field from decimal import Decimal from uuid import UUID from typing import Optional class OrderItemContract(Contract): product_id: int = Field(required=True) quantity: int = Field(ge=1, le=999) unit_price: Decimal = Field(max_digits=10, decimal_places=2) note: Optional[str] = Field(max_length=500) # allow_null=True auto-set class Spec: model = OrderItem fields = "__all__" class OrderContract(Contract): reference: UUID = Field(read_only=True) customer_name: str = Field(max_length=200) items: list[OrderItemContract] = Field(min_items=1) # Nested Contract total: Decimal = Field(max_digits=12, decimal_places=2, read_only=True) status: str = Field(choices=["pending", "confirmed", "shipped", "delivered"]) class Spec: model = Order fields = "__all__" read_only_fields = ["reference", "total"] The @computed Decorator Mark methods as computed output fields using @computed. These fields appear in output but never accept input: from aquilia.contracts import Contract, Field, computed class UserContract(Contract): first_name: str = Field(max_length=50) last_name: str = Field(max_length=50) email: str = Field() avatar_url: str = Field(read_only=True) class Spec: model = User fields = ["first_name", "last_name", "email", "avatar_url"] @computed def full_name(self, instance): """Computed from first + last name.""" return f" " @computed def initials(self, instance): """First letter of each name part.""" return "".join( part[0].upper() for part in f" ".split() ) @computed def gravatar_url(self, instance): """Generate gravatar URL from email.""" import hashlib email_hash = hashlib.md5(instance.email.lower().encode()).hexdigest() return f"https://gravatar.com/avatar/ " # Output: # Nested Contracts via Annotations When you annotate a field with another Contract class, Aquilia creates a NestedContractFacet that delegates validation to the nested Contract: class AddressContract(Contract): street: str = Field(max_length=200) city: str = Field(max_length=100) zip_code: str = Field(max_length=20) country: str = Field(max_length=100, default="US") class Spec: model = Address fields = "__all__" class CompanyContract(Contract): name: str = Field(max_length=200) # Single nested Contract headquarters: AddressContract = Field(required=True) # List of nested Contracts offices: list[AddressContract] = Field(required=False) class Spec: model = Company fields = "__all__" # Input: # , # "offices": [ # , # ] # } # Each nested object is validated through AddressContract.is_sealed() Lazy Forward References For circular references, use string annotations. Aquilia resolves them lazily from the Contract registry: from __future__ import annotations # Enable PEP 563 class DepartmentContract(Contract): name: str = Field(max_length=100) # Forward reference — EmployeeContract not yet defined manager: "EmployeeContract" = Field(required=False) employees: list["EmployeeContract"] = Field(required=False) class Spec: model = Department fields = "__all__" class EmployeeContract(Contract): name: str = Field(max_length=100) department: DepartmentContract = Field() # Direct reference (already defined) class Spec: model = Employee fields = "__all__" # Both resolve correctly at runtime via _contract_registry Optional & Union Types from typing import Optional, Union class FlexibleContract(Contract): # Optional — allows null nickname: Optional[str] = Field(max_length=50) # Same as: str | None = Field(...) # Produces: TextFacet(allow_null=True, max_length=50) # Union — polymorphic identifier: str | int = Field() # Produces: PolymorphicFacet(candidates=[TextFacet(), IntFacet()]) # Tries str first, then int class Spec: model = Flexible fields = "__all__" PEP 563 / 649 Support Aquilia's introspect_annotations() fully supports deferred evaluation of annotations via from __future__ import annotations (PEP 563). String annotations are resolved against the module's globals at Contract class creation time. from __future__ import annotations # All annotations become strings from datetime import datetime from decimal import Decimal class InvoiceContract(Contract): # These are string annotations at parse time, # resolved to actual types by introspect_annotations() amount: Decimal = Field(max_digits=10, decimal_places=2) issued_at: datetime = Field(read_only=True) notes: str | None = Field(max_length=500) class Spec: model = Invoice fields = "__all__" )

### Code Examples
```python
class UserBP(Contract):
    name = TextFacet(max_length=100)
    age = IntFacet(min_value=0)
    email = EmailFacet()
```

```python
class UserBP(Contract):
    name: str = Field(max_length=100)
    age: int = Field(ge=0)
    email: str = Field()
```

```python
from aquilia.contracts import Contract, Field


class ProductContract(Contract):
    # All Field() options:
    name: str = Field(
        default=None,           # Default value if not provided
        required=True,          # Is this field required in input?
        read_only=False,        # Exclude from input, include in output
        write_only=False,       # Include in input, exclude from output
        allow_null=False,       # Allow None values
        
        # Numeric constraints (maps to min_value/max_value)
        ge=0,                   # Greater than or equal to
        le=100,                 # Less than or equal to
        gt=None,                # Greater than (strict)
        lt=None,                # Less than (strict)
        
        # String constraints
        min_length=None,        # Minimum string length
        max_length=200,         # Maximum string length
        pattern=None,           # Regex pattern
        
        # Collection constraints
        min_items=None,         # Minimum list items
        max_items=None,         # Maximum list items
        
        # Choice constraint
        choices=None,           # Allowed values (list/dict/tuple)
        
        # Decimal constraints
        max_digits=None,        # Total digits (DecimalFacet)
        decimal_places=None,    # Decimal places (DecimalFacet)
        
        # Source mapping
        alias=None,             # Alternative name in input JSON
    )

    class Spec:
        model = Product
        fields = "__all__"
```



---

## Controller Integration
**URL**: `https://tubox.cloud/docs/contracts/integration`

Contracts / Controller Integration Controller Integration Contracts integrate deeply with Aquilia's Controllers, DI Container, Auth system, and Sessions. This page shows how Contracts work as part of the full request lifecycle. Auto-Binding to Request When a controller handler declares a Contract type hint, Aquilia automatically parses the request body and creates a Contract instance via bind_contract_to_request(): from aquilia import Controller, Post, Put, Get from myapp.contracts import ProductContract class ProductController(Controller): prefix = "/api/products" @Post("/", status_code=201) async def create(self, ctx, payload: ProductContract): """ 'payload' is automatically: 1. Parsed from request JSON/form body 2. Instantiated as ProductContract(data=body) 3. Context injected with request + DI container """ if not payload.is_sealed(): return ctx.json(payload.errors, status=422) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) @Put("/ ") async def update(self, ctx, id: int, payload: ProductContract): product = await Product.objects.get(id=id) if not payload.is_sealed(): return ctx.json(payload.errors, status=422) payload.imprint(instance=product, partial=True) await product.save() return ctx.json(ProductContract(instance=product).data) Response Rendering with Projections from aquilia import Controller, Get from myapp.contracts import ProductContract class ProductController(Controller): prefix = "/api/products" @Get("/") async def list_products(self, ctx): products = await Product.objects.all() # Minimal projection for list views bp = ProductContract( instance=products, many=True, projection="__minimal__" ) return ctx.json(bp.data) @Get("/ ") async def detail(self, ctx, id: int): product = await Product.objects.get(id=id) # Full detail projection bp = ProductContract(instance=product, projection="detail") return ctx.json(bp.data) @Get("/ /admin") async def admin_view(self, ctx, id: int): product = await Product.objects.get(id=id) # Admin projection with all fields bp = ProductContract(instance=product, projection="__all__") return ctx.json(bp.data) DI Container Integration Contracts can resolve dependencies from the DI container using the Inject facet: from aquilia.contracts import Contract, TextFacet, Inject, Hidden from aquilia.di import Singleton # Register a service in DI class PricingService: def calculate_tax(self, price: float, region: str) -> float: rates = return price * rates.get(region, 0.10) # In workspace.py: container.singleton(PricingService) class InvoiceContract(Contract): amount = FloatFacet() region = TextFacet(max_length=10) # Inject service from DI container pricing = Inject(token=PricingService) # Hidden — populated by context, never exposed in I/O created_by_id = Hidden() class Spec: model = Invoice fields = ["amount", "region"] def seal_tax_calculation(self, data): """Use injected service for validation.""" tax = self.pricing.calculate_tax(data["amount"], data["region"]) if tax > 1000: self.reject("amount", "Invoice amount exceeds tax threshold.") Auth Integration Combine Contracts with Aquilia's auth guards for secure endpoints: from aquilia import Controller, Post, Get from aquilia.auth import guard, AuthGuard from myapp.contracts import ArticleContract class ArticleController(Controller): prefix = "/api/articles" @Post("/", status_code=201) @guard(AuthGuard) # Require authentication async def create(self, ctx, payload: ArticleContract): """Create article — requires authenticated user.""" if not payload.is_sealed(): return ctx.json(payload.errors, status=422) # Inject the authenticated user as the author article = payload.imprint() article.author = ctx.user # From auth guard await article.save() return ctx.json(ArticleContract(instance=article).data, status=201) @Get("/") async def list_articles(self, ctx): """Public endpoint — no auth required.""" articles = await Article.objects.filter(published=True) return ctx.json( ArticleContract( instance=articles, many=True, projection="public" ).data ) # Contract with auth-aware validation: class AdminSettingsContract(Contract): maintenance_mode = BoolFacet(default=False) max_upload_size = IntFacet(min_value=1, max_value=100) class Spec: model = Settings fields = ["maintenance_mode", "max_upload_size"] async def async_seal_admin_only(self, data): """Only admins can change maintenance mode.""" if data.get("maintenance_mode") and not self.context.get("is_admin"): self.reject("maintenance_mode", "Only admins can enable maintenance mode.") Sessions Integration Contracts can access session data for validation and conditional logic: from aquilia import Controller, Post from aquilia.sessions import session, authenticated from myapp.contracts import CartContract class CartController(Controller): prefix = "/api/cart" @Post("/checkout") @authenticated # Require authenticated session async def checkout(self, ctx): """Checkout flow using session data + Contract.""" # Get cart items from session cart_items = ctx.session.get("cart", []) # Validate checkout data with Contract bp = CheckoutContract(data= ) if not bp.is_sealed(): return ctx.json(bp.errors, status=422) order = bp.imprint() order.user = ctx.session.principal await order.save() # Clear cart from session ctx.session.delete("cart") return ctx.json(OrderContract(instance=order).data, status=201) class CheckoutContract(Contract): items = ListFacet(child=IntFacet(), min_items=1) shipping_address = NestedContractFacet(AddressContract) class Spec: model = Order fields = ["items", "shipping_address"] def seal_cart_not_empty(self, data): if not data.get("items"): self.reject("items", "Your cart is empty.") Full CRUD Example from aquilia import Controller, Get, Post, Put, Patch, Delete from aquilia.auth import guard, AuthGuard from myapp.contracts import ProductContract class ProductController(Controller): prefix = "/api/products" @Get("/") async def list(self, ctx): products = await Product.objects.all() return ctx.json( ProductContract(instance=products, many=True, projection="__minimal__").data ) @Get("/ ") async def retrieve(self, ctx, id: int): product = await Product.objects.get(id=id) return ctx.json(ProductContract(instance=product, projection="detail").data) @Post("/", status_code=201) @guard(AuthGuard) async def create(self, ctx, payload: ProductContract): if not await payload.is_sealed_async(): return ctx.json(payload.errors, status=422) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) @Patch("/ ") @guard(AuthGuard) async def partial_update(self, ctx, id: int, payload: ProductContract): product = await Product.objects.get(id=id) # partial=True: only validate provided fields bp = ProductContract(data=await ctx.json(), partial=True) if not bp.is_sealed(): return ctx.json(bp.errors, status=422) bp.imprint(instance=product, partial=True) await product.save() return ctx.json(ProductContract(instance=product).data) @Delete("/ ", status_code=204) @guard(AuthGuard) async def destroy(self, ctx, id: int): product = await Product.objects.get(id=id) await product.delete() return ctx.empty() Utility Functions from aquilia.contracts.integration import ( bind_contract_to_request, render_contract_response, resolve_contract_from_annotation, is_contract_class, is_projected_contract, ) # Check if a class is a Contract is_contract_class(ProductContract) # True is_contract_class(str) # False # Check if it's a projected Contract reference is_projected_contract(ProductContract["summary"]) # True # Resolve Contract from a type annotation bp_class = resolve_contract_from_annotation(handler_param_annotation) # Returns (ContractClass, projection_name) or None # Bind Contract to an incoming request (used internally by controller engine) bp = await bind_contract_to_request(ProductContract, request, container) # Render model data through Contract for response data = render_contract_response(ProductContract, instance, projection="summary") )

### Code Examples
```python
from aquilia import Controller, Post, Put, Get
from myapp.contracts import ProductContract


class ProductController(Controller):
    prefix = "/api/products"

    @Post("/", status_code=201)
    async def create(self, ctx, payload: ProductContract):
        """
        'payload' is automatically:
        1. Parsed from request JSON/form body
        2. Instantiated as ProductContract(data=body)
        3. Context injected with request + DI container
        """
        if not payload.is_sealed():
            return ctx.json(payload.errors, status=422)

        product = payload.imprint()
        await product.save()
        return ctx.json(ProductContract(instance=product).data, status=201)

    @Put("/{id:int}")
    async def update(self, ctx, id: int, payload: ProductContract):
        product = await Product.objects.get(id=id)

        if not payload.is_sealed():
            return ctx.json(payload.errors, status=422)

        payload.imprint(instance=product, partial=True)
        await product.save()
        return ctx.json(ProductContract(instance=product).data)
```

```python
from aquilia import Controller, Get
from myapp.contracts import ProductContract


class ProductController(Controller):
    prefix = "/api/products"

    @Get("/")
    async def list_products(self, ctx):
        products = await Product.objects.all()
        
        # Minimal projection for list views
        bp = ProductContract(
            instance=products,
            many=True,
            projection="__minimal__"
        )
        return ctx.json(bp.data)

    @Get("/{id:int}")
    async def detail(self, ctx, id: int):
        product = await Product.objects.get(id=id)
        
        # Full detail projection
        bp = ProductContract(instance=product, projection="detail")
        return ctx.json(bp.data)

    @Get("/{id:int}/admin")
    async def admin_view(self, ctx, id: int):
        product = await Product.objects.get(id=id)
        
        # Admin projection with all fields
        bp = ProductContract(instance=product, projection="__all__")
        return ctx.json(bp.data)
```

```python
from aquilia.contracts import Contract, TextFacet, Inject, Hidden
from aquilia.di import Singleton


# Register a service in DI
class PricingService:
    def calculate_tax(self, price: float, region: str) -> float:
        rates = {"US": 0.08, "EU": 0.20, "UK": 0.20}
        return price * rates.get(region, 0.10)

# In workspace.py: container.singleton(PricingService)


class InvoiceContract(Contract):
    amount = FloatFacet()
    region = TextFacet(max_length=10)
    
    # Inject service from DI container
    pricing = Inject(token=PricingService)
    
    # Hidden — populated by context, never exposed in I/O
    created_by_id = Hidden()

    class Spec:
        model = Invoice
        fields = ["amount", "region"]

    def seal_tax_calculation(self, data):
        """Use injected service for validation."""
        tax = self.pricing.calculate_tax(data["amount"], data["region"])
        if tax > 1000:
            self.reject("amount", "Invoice amount exceeds tax threshold.")
```



---

## OpenAPI Schemas
**URL**: `https://tubox.cloud/docs/contracts/schemas`

Contracts / OpenAPI Schemas OpenAPI Schemas Contracts auto-generate JSON Schema and OpenAPI component schemas. Every Facet contributes its schema fragment, and Projections produce per-view schemas — all without manual schema writing. Generating JSON Schema from aquilia.contracts.schema import generate_schema # Generate JSON Schema for a Contract schema = generate_schema(ProductContract) print(schema) # , # "name": , # "price": , # "sku": , # "category": , # "is_active": , # "tags": }, # }, # "required": ["name", "price", "sku"] # } # Schema for a specific projection schema = ProductContract.to_schema(projection="__minimal__") # Only includes: id, name, price, slug # Schema for input mode (excludes read_only fields) schema = ProductContract.to_schema(mode="input") # Schema for output mode (excludes write_only fields) schema = ProductContract.to_schema(mode="output") OpenAPI Component Schemas Generate OpenAPI components.schemas for multiple Contracts at once, with per-projection variants: from aquilia.contracts.schema import generate_component_schemas # Generate component schemas for all Contracts components = generate_component_schemas([ ProductContract, UserContract, OrderContract, ]) print(components) # , # "ProductContract_minimal": , # "ProductContract_detail": , # "UserContract": , # "OrderContract": , # } # This output slots directly into your OpenAPI spec: # openapi_spec["components"]["schemas"] = components Per-Facet Schema Output Each Facet type generates appropriate JSON Schema fragments: Facet JSON Schema Output ' }, ' }, ' }, ' }, ' }, ' }, ' }, ' }, ' }, ' }, , "minItems": N, "maxItems": N}' }, }' }, ' }, ' }, ].map((row, i) => ( ))} Integration with OpenAPI Endpoint from aquilia import Controller, Get from aquilia.contracts.schema import generate_component_schemas from myapp.contracts import ProductContract, UserContract, OrderContract class OpenAPIController(Controller): prefix = "/api" @Get("/openapi.json") async def openapi_spec(self, ctx): schemas = generate_component_schemas([ ProductContract, UserContract, OrderContract, ]) spec = , "components": , "paths": # Your route definitions } return ctx.json(spec) )

### Code Examples
```python
from aquilia.contracts.schema import generate_schema


# Generate JSON Schema for a Contract
schema = generate_schema(ProductContract)
print(schema)
# {
#   "type": "object",
#   "properties": {
#     "id": {"type": "integer", "readOnly": true},
#     "name": {"type": "string", "maxLength": 200},
#     "price": {"type": "number", "minimum": 0},
#     "sku": {"type": "string", "maxLength": 50, "pattern": "^[A-Z0-9-]+$"},
#     "category": {"type": "string", "enum": ["electronics", "clothing", "food"]},
#     "is_active": {"type": "boolean", "default": true},
#     "tags": {"type": "array", "items": {"type": "string", "maxLength": 50}},
#   },
#   "required": ["name", "price", "sku"]
# }


# Schema for a specific projection
schema = ProductContract.to_schema(projection="__minimal__")
# Only includes: id, name, price, slug

# Schema for input mode (excludes read_only fields)
schema = ProductContract.to_schema(mode="input")

# Schema for output mode (excludes write_only fields)
schema = ProductContract.to_schema(mode="output")
```

```python
from aquilia.contracts.schema import generate_component_schemas


# Generate component schemas for all Contracts
components = generate_component_schemas([
    ProductContract,
    UserContract,
    OrderContract,
])

print(components)
# {
#   "ProductContract": { ... default projection schema ... },
#   "ProductContract_minimal": { ... minimal projection schema ... },
#   "ProductContract_detail": { ... detail projection schema ... },
#   "UserContract": { ... },
#   "OrderContract": { ... },
# }

# This output slots directly into your OpenAPI spec:
# openapi_spec["components"]["schemas"] = components
```

```python
from aquilia import Controller, Get
from aquilia.contracts.schema import generate_component_schemas
from myapp.contracts import ProductContract, UserContract, OrderContract


class OpenAPIController(Controller):
    prefix = "/api"

    @Get("/openapi.json")
    async def openapi_spec(self, ctx):
        schemas = generate_component_schemas([
            ProductContract,
            UserContract,
            OrderContract,
        ])

        spec = {
            "openapi": "3.1.0",
            "info": {"title": "My API", "version": "1.0.0"},
            "components": {"schemas": schemas},
            "paths": { ... }  # Your route definitions
        }

        return ctx.json(spec)
```



---

## Contract Faults
**URL**: `https://tubox.cloud/docs/contracts/faults`

Contracts / Faults Contract Faults Contracts use structured fault types instead of bare exceptions. All Contract errors are part of the CONTRACT fault domain and integrate seamlessly with the AquilaFaults error handling system. Fault Taxonomy , , , , , , ].map((item, i) => ( ))} CastFault Raised when a Facet cannot coerce a raw value to the expected Python type: from aquilia.contracts.exceptions import CastFault # CastFault is raised internally during Phase 1 (Cast) # Typically caught by the Contract and added to errors dict # Example triggers: # IntFacet receives "not a number" # DateTimeFacet receives "invalid date" # BoolFacet receives [1, 2, 3] # EmailFacet receives "not@an@email" try: facet = IntFacet() facet.cast("hello") except CastFault as e: print(e.field) # "quantity" print(e.message) # "Expected integer, got str" print(e.code) # "BP100" SealFault Raised when validation fails — either from Facet constraints or from custom seal methods: from aquilia.contracts.exceptions import SealFault bp = ProductContract(data= ) # SealFault accumulates all errors bp.is_sealed() print(bp.errors) # # With raise_fault=True: try: bp.is_sealed(raise_fault=True) except SealFault as e: print(e.field_errors) # dict of field → error messages print(e.error_count) # Total number of errors print(e.as_response_body()) # # } Handling Contract Faults from aquilia import Controller, Post from aquilia.faults import fault_handler from aquilia.contracts.exceptions import SealFault class ProductController(Controller): prefix = "/api/products" @Post("/", status_code=201) async def create(self, ctx, payload: ProductContract): # Pattern 1: Check and return errors if not payload.is_sealed(): return ctx.json(payload.errors, status=422) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) # Pattern 2: Global fault handler for SealFault @fault_handler(SealFault) async def handle_seal_fault(ctx, fault): """Auto-converts SealFault to 422 response.""" return ctx.json(fault.as_response_body(), status=422) # Register in workspace: # workspace = Workspace(fault_handlers=[handle_seal_fault]) # Pattern 3: raise_fault=True for exception-based flow class StrictProductController(Controller): prefix = "/api/strict/products" @Post("/") async def create(self, ctx, payload: ProductContract): # This raises SealFault if validation fails # The global fault handler catches it automatically payload.is_sealed(raise_fault=True) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) Integration with AquilaFaults All Contract faults inherit from Fault and integrate with Aquilia's fault engine: from aquilia.faults.core import Fault, Severity, FaultDomain from aquilia.contracts.exceptions import SealFault, CastFault # All Contract faults have: fault = SealFault(field="email", message="Invalid email") fault.code # "BP200" fault.severity # Severity.WARN fault.domain # FaultDomain.CONTRACT (or VALIDATION) fault.public # True (safe to show to user) fault.retryable # False (fix the input, don't retry) # They appear in the FaultEngine's error log # They are caught by global fault handlers # They integrate with the trace/observability system )

### Code Examples
```python
from aquilia.contracts.exceptions import CastFault

# CastFault is raised internally during Phase 1 (Cast)
# Typically caught by the Contract and added to errors dict

# Example triggers:
# IntFacet receives "not a number"
# DateTimeFacet receives "invalid date"
# BoolFacet receives [1, 2, 3]
# EmailFacet receives "not@an@email"

try:
    facet = IntFacet()
    facet.cast("hello")
except CastFault as e:
    print(e.field)     # "quantity"
    print(e.message)   # "Expected integer, got str"
    print(e.code)      # "BP100"
```

```python
from aquilia.contracts.exceptions import SealFault

bp = ProductContract(data={"name": "", "price": -10})

# SealFault accumulates all errors
bp.is_sealed()
print(bp.errors)
# {"name": ["This field is required."], "price": ["Must be >= 0."]}

# With raise_fault=True:
try:
    bp.is_sealed(raise_fault=True)
except SealFault as e:
    print(e.field_errors)    # dict of field → error messages
    print(e.error_count)     # Total number of errors
    print(e.as_response_body())
    # {
    #   "fault_code": "BP200",
    #   "fault_domain": "CONTRACT",
    #   "message": "Validation failed",
    #   "field_errors": {
    #     "name": ["This field is required."],
    #     "price": ["Must be >= 0."]
    #   }
    # }
```

```python
from aquilia import Controller, Post
from aquilia.faults import fault_handler
from aquilia.contracts.exceptions import SealFault


class ProductController(Controller):
    prefix = "/api/products"

    @Post("/", status_code=201)
    async def create(self, ctx, payload: ProductContract):
        # Pattern 1: Check and return errors
        if not payload.is_sealed():
            return ctx.json(payload.errors, status=422)

        product = payload.imprint()
        await product.save()
        return ctx.json(ProductContract(instance=product).data, status=201)


# Pattern 2: Global fault handler for SealFault
@fault_handler(SealFault)
async def handle_seal_fault(ctx, fault):
    """Auto-converts SealFault to 422 response."""
    return ctx.json(fault.as_response_body(), status=422)

# Register in workspace:
# workspace = Workspace(fault_handlers=[handle_seal_fault])


# Pattern 3: raise_fault=True for exception-based flow
class StrictProductController(Controller):
    prefix = "/api/strict/products"

    @Post("/")
    async def create(self, ctx, payload: ProductContract):
        # This raises SealFault if validation fails
        # The global fault handler catches it automatically
        payload.is_sealed(raise_fault=True)
        
        product = payload.imprint()
        await product.save()
        return ctx.json(ProductContract(instance=product).data, status=201)
```



---

## Database Engine
**URL**: `https://tubox.cloud/docs/database`

Docs / Database Engine Database Engine Aquilia's database layer is a thin, async-first abstraction over multiple backends. One API — SQLite, PostgreSQL, MySQL, or Oracle. All operations use ? placeholders; the adapter normalises to the native param style. How it works AquiliaDatabase is a DI-registered @service(scope="app"). On startup the LifecycleCoordinator calls on_startup(), which opens a connection (with retry logic). All queries go through backend adapters — SQLiteAdapter, PostgresAdapter (asyncpg), MySQLAdapter (aiomysql), OracleAdapter (python-oracledb). The engine records every query duration and emits spans to the active trace for the query inspector. Quick Start Configure the database in workspace.py via the Integration builder: from aquilia.workspace import Workspace, Module from aquilia.integrations import Integration from aquilia.db.configs import PostgresConfig workspace = ( Workspace("my-api") .add_module(Module("users")) .integrate(Integration.database( config=PostgresConfig( host="localhost", database="mydb", user="admin", password="secret", pool_size=10, ) )) .build() ) Or use a URL string: Integration.database(url="postgresql://admin:secret@localhost/mydb") Integration.database(url="sqlite:///app.db") Integration.database(url="mysql://root:pass@localhost/mydb") Supported Backends , , , , ].map(b => ( ))} Raw Queries Use the AquiliaDatabase instance directly for raw SQL. All methods accept ? placeholders. from aquilia.db import get_database db = get_database() # SELECT all rows rows = await db.fetch_all("SELECT * FROM users WHERE active = ?", [True]) # SELECT one row row = await db.fetch_one("SELECT * FROM users WHERE id = ?", [42]) # SELECT scalar value count = await db.fetch_val("SELECT COUNT(*) FROM users") # INSERT / UPDATE / DELETE result = await db.execute("INSERT INTO logs (message) VALUES (?)", ["app started"]) print(result.lastrowid) # Bulk insert await db.execute_many( "INSERT INTO tags (name) VALUES (?)", [["python"], ["async"], ["orm"]], ) DI Injection AquiliaDatabase is registered as a DI service. Inject it into services or controllers with @inject: from aquilia.db import AquiliaDatabase from aquilia.di import inject class UserService: @inject def __init__(self, db: AquiliaDatabase): self.db = db async def get_active_users(self): return await self.db.fetch_all("SELECT * FROM users WHERE active = ?", [True]) Properties Property Type Description ))} Multi-Database Use configure_database() with named aliases to manage multiple connections: from aquilia.db import configure_database, get_database from aquilia.db.configs import PostgresConfig, SqliteConfig # Primary (Postgres) configure_database(config=PostgresConfig(host="pg-host", name="app"), alias="default") # Read replica configure_database(config=PostgresConfig(host="pg-replica", name="app"), alias="replica") # Analytics sidecar configure_database(config=SqliteConfig(path="analytics.db"), alias="analytics") # Retrieve by alias db = get_database() # "default" replica = get_database("replica") stats = get_database("analytics") Engine API )

### Code Examples
```python
from aquilia.workspace import Workspace, Module
from aquilia.integrations import Integration
from aquilia.db.configs import PostgresConfig

workspace = (
    Workspace("my-api")
    .add_module(Module("users"))
    .integrate(Integration.database(
        config=PostgresConfig(
            host="localhost",
            database="mydb",
            user="admin",
            password="secret",
            pool_size=10,
        )
    ))
    .build()
)
```

```python
Integration.database(url="postgresql://admin:secret@localhost/mydb")
Integration.database(url="sqlite:///app.db")
Integration.database(url="mysql://root:pass@localhost/mydb")
```

```python
from aquilia.db import get_database

db = get_database()

# SELECT all rows
rows = await db.fetch_all("SELECT * FROM users WHERE active = ?", [True])

# SELECT one row
row = await db.fetch_one("SELECT * FROM users WHERE id = ?", [42])

# SELECT scalar value
count = await db.fetch_val("SELECT COUNT(*) FROM users")

# INSERT / UPDATE / DELETE
result = await db.execute("INSERT INTO logs (message) VALUES (?)", ["app started"])
print(result.lastrowid)

# Bulk insert
await db.execute_many(
    "INSERT INTO tags (name) VALUES (?)",
    [["python"], ["async"], ["orm"]],
)
```



---

## AquiliaDatabase
**URL**: `https://tubox.cloud/docs/database/engine`

Docs / Database / AquiliaDatabase AquiliaDatabase The central async database engine — connection lifecycle, raw query API, transactions, savepoints, and introspection. Registered as a DI @service(scope="app"). AquiliaDatabase Source: aquilia/db/engine.py:89 · DI scope: app Constructor class AquiliaDatabase: def __init__( self, url: str | None = None, *, config: DatabaseConfig | None = None, connect_retries: int = 3, connect_retry_delay: float = 0.5, **options, ): ... Param Type Description ))} from aquilia.db import AquiliaDatabase from aquilia.db.configs import PostgresConfig, SqliteConfig # URL string db = AquiliaDatabase("sqlite:///app.db") db = AquiliaDatabase("postgresql://admin:s3cr3t@localhost/mydb") # Typed config (recommended — IDE autocompletion) db = AquiliaDatabase(config=PostgresConfig( host="localhost", database="mydb", user="admin", password="s3cr3t", pool_size=20, sslmode="require", )) # Custom retry db = AquiliaDatabase("postgresql://...", connect_retries=5, connect_retry_delay=1.0) Connection Management Method Description ))} Query Methods Method Returns Description ))} # All methods use ? placeholders — adapter normalises per backend rows = await db.fetch_all("SELECT * FROM users WHERE active = ?", [True]) row = await db.fetch_one("SELECT * FROM users WHERE id = ?", [42]) count = await db.fetch_val("SELECT COUNT(*) FROM orders WHERE status = ?", ["paid"]) res = await db.execute("UPDATE users SET active = ? WHERE id = ?", [False, 99]) print(res.rowcount) # rows affected await db.execute_many( "INSERT INTO tags (name) VALUES (?)", [["python"], ["async"], ["orm"]], ) Transactions Use the transaction() context manager for automatic commit / rollback. For manual control call begin(), commit(), rollback() directly. # Context manager (recommended) async with db.transaction(): await db.execute("INSERT INTO orders ...") await db.execute("UPDATE inventory ...") # Commits if no exception, rolls back otherwise # Manual await db.begin(isolation="REPEATABLE READ") try: await db.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", [100, 1]) await db.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", [100, 2]) await db.commit() except Exception: await db.rollback() raise Savepoints Nested checkpoints inside a transaction. Name must match [a-zA-Z_][a-zA-Z0-9_]*. await db.begin() await db.savepoint("before_risky_op") try: await db.execute("DELETE FROM temporary_data WHERE expired = ?", [True]) await db.release_savepoint("before_risky_op") # commit savepoint except Exception: await db.rollback_to_savepoint("before_risky_op") # undo only this block await db.commit() ⚠️ Prefer atomic() from the ORM layer when working with Model.save() — it integrates with signals and on_commit hooks. Use db.transaction() for raw SQL blocks only. Schema Introspection Method Returns Description ))} tables = await db.get_tables() # ["users", "posts", "tags", "migrations"] exists = await db.table_exists("sessions") cols = await db.get_columns("users") for col in cols: print(f" : ") Module-Level Functions from aquilia.db import configure_database, get_database, set_database, get_all_databases # Configure (called automatically by Integration.database()) db = configure_database(url="sqlite:///app.db") db = configure_database(config=PostgresConfig(...), alias="primary") # Retrieve db = get_database() # default db = get_database("primary") # named alias # Replace an existing instance set_database(my_db, alias="default") # All configured databases all_dbs = get_all_databases() # Faults Fault When raised ))} from aquilia.models import DatabaseConnectionFault, QueryFault try: rows = await db.fetch_all("SELECT * FROM users") except QueryFault as e: print(e.reason, e.metadata) except DatabaseConnectionFault as e: print("Connection lost:", e.reason) Overview Config Classes )

### Code Examples
```python
class AquiliaDatabase:
    def __init__(
        self,
        url: str | None = None,
        *,
        config: DatabaseConfig | None = None,
        connect_retries: int = 3,
        connect_retry_delay: float = 0.5,
        **options,
    ): ...
```

```python
from aquilia.db import AquiliaDatabase
from aquilia.db.configs import PostgresConfig, SqliteConfig

# URL string
db = AquiliaDatabase("sqlite:///app.db")
db = AquiliaDatabase("postgresql://admin:s3cr3t@localhost/mydb")

# Typed config (recommended — IDE autocompletion)
db = AquiliaDatabase(config=PostgresConfig(
    host="localhost", database="mydb", user="admin", password="s3cr3t",
    pool_size=20, sslmode="require",
))

# Custom retry
db = AquiliaDatabase("postgresql://...", connect_retries=5, connect_retry_delay=1.0)
```

```python
# All methods use ? placeholders — adapter normalises per backend
rows  = await db.fetch_all("SELECT * FROM users WHERE active = ?", [True])
row   = await db.fetch_one("SELECT * FROM users WHERE id = ?", [42])
count = await db.fetch_val("SELECT COUNT(*) FROM orders WHERE status = ?", ["paid"])

res   = await db.execute("UPDATE users SET active = ? WHERE id = ?", [False, 99])
print(res.rowcount)   # rows affected

await db.execute_many(
    "INSERT INTO tags (name) VALUES (?)",
    [["python"], ["async"], ["orm"]],
)
```



---

## Config Classes
**URL**: `https://tubox.cloud/docs/database/configs`

Docs / Database / Config Classes Config Classes Typed, IDE-friendly configuration dataclasses for each backend. No URL string typos — just Python with autocompletion. DatabaseConfig (base) All backend configs inherit from DatabaseConfig. Common pool, retry, and behavior settings. Field Default Description ))} SqliteConfig built-in SQLite via Aquilia's native async SQLite driver. No extra packages required. WAL mode enabled by default for concurrent reads. from aquilia.db.configs import SqliteConfig # File-based cfg = SqliteConfig(path="data/app.db") # In-memory (great for tests) cfg = SqliteConfig(path=":memory:") # Production settings cfg = SqliteConfig( path="data/prod.db", journal_mode="WAL", # WAL | DELETE | TRUNCATE | PERSIST | MEMORY | OFF foreign_keys=True, # PRAGMA foreign_keys = ON busy_timeout=5000, # PRAGMA busy_timeout = 5000 (ms) auto_migrate=True, conn_health_checks=True, ) # From URL cfg = SqliteConfig.from_url("sqlite:///data/app.db") Field Default Description ))} PostgresConfig pip install asyncpg PostgreSQL via asyncpg. Supports SSL, connection pool min/max, and schema selection. Both name and database are accepted as the database name. from aquilia.db.configs import PostgresConfig # Minimal cfg = PostgresConfig( host="localhost", database="mydb", # or: name="mydb" user="admin", password="secret", ) # Production with SSL + pooling cfg = PostgresConfig( host="db.example.com", port=5432, database="prod_db", user="app_user", password="s3cr3t", sslmode="require", # disable | allow | prefer | require | verify-full schema="public", pool_size=20, pool_min_size=5, pool_max_size=50, conn_health_checks=True, conn_max_age=600, ) # From URL cfg = PostgresConfig.from_url("postgresql://admin:secret@localhost:5432/mydb", pool_size=10) Field Default Description ))} MysqlConfig pip install aiomysql MySQL and MariaDB via aiomysql. Defaults to utf8mb4 charset with utf8mb4_unicode_ci collation. from aquilia.db.configs import MysqlConfig cfg = MysqlConfig( host="mysql.example.com", database="prod_db", # or: name="prod_db" user="app_user", password="s3cr3t", charset="utf8mb4", collation="utf8mb4_unicode_ci", pool_size=15, ) cfg = MysqlConfig.from_url("mysql://root:pass@localhost:3306/mydb") Field Default Description ))} OracleConfig pip install oracledb Oracle via python-oracledb. Thin mode by default — no Oracle Client installation required. Use service_name or sid. from aquilia.db.configs import OracleConfig # Service name (recommended) cfg = OracleConfig( host="oracle.example.com", database="PROD_SERVICE", # alias for service_name user="app_user", password="tiger", pool_size=20, ) # SID-based cfg = OracleConfig( host="oracle.example.com", sid="ORCL", user="scott", password="tiger", ) # Thick mode (requires Oracle Client) cfg = OracleConfig( host="oracle.example.com", database="PROD", user="scott", password="tiger", thick_mode=True, encoding="UTF-8", ) cfg = OracleConfig.from_url("oracle://scott:tiger@oracle.example.com:1521/PROD") Using with Integration Pass any config class to Integration.database(config=...) in your workspace: from aquilia.workspace import Workspace, Module from aquilia.integrations import Integration from aquilia.db.configs import PostgresConfig, SqliteConfig workspace = ( Workspace("my-api") .add_module(Module("users")) .integrate(Integration.database( config=PostgresConfig( host="db.example.com", database="prod_db", user="admin", password="secret", pool_size=20, sslmode="require", ) )) .build() ) # Test workspace with in-memory SQLite test_workspace = ( Workspace("my-api-test") .add_module(Module("users")) .integrate(Integration.database( config=SqliteConfig(path=":memory:", auto_migrate=True) )) .build() ) from_url() Classmethod Every config class provides a from_url() classmethod. DatabaseConfig.from_url() auto-detects the backend from the URL scheme. from aquilia.db.configs import DatabaseConfig # Auto-detect (returns the correct subclass) cfg = DatabaseConfig.from_url("postgresql://admin:secret@localhost/mydb") # → PostgresConfig instance cfg = DatabaseConfig.from_url("sqlite:///data/app.db") # → SqliteConfig instance # Override specific fields cfg = DatabaseConfig.from_url("postgresql://admin:secret@localhost/mydb", pool_size=20) AquiliaDatabase SQLite Backend )

### Code Examples
```python
from aquilia.db.configs import SqliteConfig

# File-based
cfg = SqliteConfig(path="data/app.db")

# In-memory (great for tests)
cfg = SqliteConfig(path=":memory:")

# Production settings
cfg = SqliteConfig(
    path="data/prod.db",
    journal_mode="WAL",        # WAL | DELETE | TRUNCATE | PERSIST | MEMORY | OFF
    foreign_keys=True,         # PRAGMA foreign_keys = ON
    busy_timeout=5000,         # PRAGMA busy_timeout = 5000 (ms)
    auto_migrate=True,
    conn_health_checks=True,
)

# From URL
cfg = SqliteConfig.from_url("sqlite:///data/app.db")
```

```python
from aquilia.db.configs import PostgresConfig

# Minimal
cfg = PostgresConfig(
    host="localhost",
    database="mydb",   # or: name="mydb"
    user="admin",
    password="secret",
)

# Production with SSL + pooling
cfg = PostgresConfig(
    host="db.example.com",
    port=5432,
    database="prod_db",
    user="app_user",
    password="s3cr3t",
    sslmode="require",          # disable | allow | prefer | require | verify-full
    schema="public",
    pool_size=20,
    pool_min_size=5,
    pool_max_size=50,
    conn_health_checks=True,
    conn_max_age=600,
)

# From URL
cfg = PostgresConfig.from_url("postgresql://admin:secret@localhost:5432/mydb", pool_size=10)
```

```python
from aquilia.db.configs import MysqlConfig

cfg = MysqlConfig(
    host="mysql.example.com",
    database="prod_db",    # or: name="prod_db"
    user="app_user",
    password="s3cr3t",
    charset="utf8mb4",
    collation="utf8mb4_unicode_ci",
    pool_size=15,
)

cfg = MysqlConfig.from_url("mysql://root:pass@localhost:3306/mydb")
```



---

## AquilAuth — Enterprise-Grade Security
**URL**: `https://tubox.cloud/docs/auth`

Security & Authentication AquilAuth — Enterprise-Grade Security Aquilia's authentication architecture is built on three pillars: Identity (the principal), PasswordCredential (the proof of identity), and AuthGuard (policy enforcement). It is async-first, deeply integrated with the dependency injection system, and provides zero-config setups for both API tokens and browser sessions. Authentication Pipeline When a request enters the application, it flows through a unified middleware chain that automatically parses authentication credentials, resolves sessions, and loads the active identity. , , , , , ].map((b, i) => ( } ))} CREDENTIAL TYPES , , , , ].map((c, i) => ( ))} Subsystem Components , , , , , , , , , ].map((m, i) => ( ))} End-to-End Application Integration Rather than configuring independent components, this guide walks you through building a complete user registration, authentication, and endpoint authorization system backed by the database ORM and dependency injection. 01. Define the User DB Model Extend the base Model to define columns for user names, emails, active flags, comma-separated roles, and cryptographically hashed passwords. from aquilia.models import Model from aquilia.models.fields import CharField, EmailField, BooleanField, DateTimeField class User(Model): table = "users" name = CharField(max_length=150) email = EmailField(unique=True) password_hash = CharField(max_length=255) is_active = BooleanField(default=True) roles = CharField(max_length=255, default="user") # e.g. "user,admin" created_at = DateTimeField(auto_now_add=True) 02. Establish Request Validation Contracts Create incoming schema definitions (Contracts) to enforce type validation, boundary checks, and sanitizer casts on incoming API requests automatically. from aquilia.contracts import Contract, Field class SignUpContract(Contract): name = Field[str]() email = Field[str]() password = Field[str]() class SignInContract(Contract): email = Field[str]() password = Field[str]() 03. Implement the Auth Controller Build controller methods to handle user creation, token issuance, and protected dashboard paths. Decorating methods with @authenticated or @roles_required isolates access boundaries. from aquilia.controller import Controller, GET, POST from aquilia.response import Response from aquilia.auth.decorators import authenticated, roles_required from aquilia.auth.manager import AuthManager from aquilia.auth.core import Identity, IdentityType, IdentityStatus from contracts.auth import SignUpContract, SignInContract from models.user import User class AuthController(Controller): prefix = "/auth" @POST("/signup") async def signup(self, ctx, contract: SignUpContract): """Register a new user, hashing their password hash.""" data = contract.validated_data # Verify if record exists existing = await User.objects.filter(email=data["email"]).first() if existing: return Response.json( , status=400) auth_manager = ctx.container.resolve(AuthManager) hashed = auth_manager.password_hasher.hash(data["password"]) user = await User.objects.create( name=data["name"], email=data["email"], password_hash=hashed, is_active=True, roles="user" ) return Response.json( ) @POST("/login") async def login(self, ctx, contract: SignInContract): """Authenticate user credentials and issue security tokens.""" data = contract.validated_data auth_manager = ctx.container.resolve(AuthManager) user = await User.objects.filter(email=data["email"]).first() if not user or not user.is_active: return Response.json( , status=401) # Initialize seed identity for dynamic stores identity = Identity( id=str(user.id), type=IdentityType.USER, attributes= , status=IdentityStatus.ACTIVE, ) try: # Complete login and return Issued Access and Refresh Tokens auth_result = await auth_manager.sign_in( username=user.email, password=data["password"], identity=identity, ) return Response.json( ) except Exception as e: return Response.json( , status=401) @GET("/profile") @authenticated async def profile(self, ctx, user: Identity): """Authenticated endpoint returns current user info.""" return Response.json( ) @GET("/admin-panel") @roles_required("admin") async def admin_panel(self, ctx, user: Identity): """Admin restricted route.""" return Response.json( ) 04. Implement Database Adapters for Auth Storage Map the authentication protocols (`IdentityStore` and `CredentialStore`) directly to your database queries to resolve principals and store password updates securely. from typing import Any from aquilia.auth.core import IdentityStore, CredentialStore, Identity, PasswordCredential, IdentityStatus, IdentityType from models.user import User class DatabaseIdentityStore(IdentityStore): async def get(self, identity_id: str) -> Identity | None: user = await User.objects.filter(id=identity_id).first() if not user or not user.is_active: return None return Identity( id=str(user.id), type=IdentityType.USER, attributes= , status=IdentityStatus.ACTIVE, ) async def get_by_attribute(self, attribute: str, value: Any) -> Identity | None: if attribute == "email": user = await User.objects.filter(email=value).first() if user: return await self.get(str(user.id)) return None class DatabaseCredentialStore(CredentialStore): async def get_password(self, identity_id: str) -> PasswordCredential | None: user = await User.objects.filter(id=identity_id).first() if not user: return None return PasswordCredential( identity_id=identity_id, password_hash=user.password_hash ) async def create_password(self, credential: PasswordCredential) -> None: await User.objects.filter(id=credential.identity_id).update( password_hash=credential.password_hash ) async def update_password(self, credential: PasswordCredential) -> None: await self.create_password(credential) 05. Bootstrap DI Registration and Middleware Register your database store overrides in the dependency injection container, append the AuthMiddleware stack, and launch the application. from aquilia import Aquilia from aquilia.sessions import SessionEngine from aquilia.auth.core import IdentityStore, CredentialStore from aquilia.auth.manager import AuthManager from aquilia.auth.integration.di_providers import register_auth_providers from aquilia.auth.middleware import AuthMiddleware from stores.database import DatabaseIdentityStore, DatabaseCredentialStore from controllers.auth import AuthController app = Aquilia() # 1. Register custom DB auth store adapters before initializing auth providers app.container.register(IdentityStore, DatabaseIdentityStore) app.container.register(CredentialStore, DatabaseCredentialStore) # 2. Register all default providers (PasswordHasher, TokenManager, etc.) register_auth_providers(app.container) # 3. Resolve required managers from container session_engine = app.container.resolve(SessionEngine) auth_manager = app.container.resolve(AuthManager) # 4. Apply the main auth middleware to intercept requests using pluggable backends app.use(AuthMiddleware( auth_manager=auth_manager, session_engine=session_engine, require_auth=False, # Enforce opt-in per route using decorators )) # 5. Bind controller endpoints app.register_controller(AuthController) Identity Object Structure The principal identity is immutable once instantiated, representing a secure entity descriptor inside RequestCtx. Field Type Description ))} )

### Code Examples
```python
from aquilia.models import Model
from aquilia.models.fields import CharField, EmailField, BooleanField, DateTimeField

class User(Model):
    table = "users"

    name = CharField(max_length=150)
    email = EmailField(unique=True)
    password_hash = CharField(max_length=255)
    is_active = BooleanField(default=True)
    roles = CharField(max_length=255, default="user")  # e.g. "user,admin"
    created_at = DateTimeField(auto_now_add=True)
```

```python
from aquilia.contracts import Contract, Field

class SignUpContract(Contract):
    name = Field[str]()
    email = Field[str]()
    password = Field[str]()

class SignInContract(Contract):
    email = Field[str]()
    password = Field[str]()
```

```python
from aquilia.controller import Controller, GET, POST
from aquilia.response import Response
from aquilia.auth.decorators import authenticated, roles_required
from aquilia.auth.manager import AuthManager
from aquilia.auth.core import Identity, IdentityType, IdentityStatus
from contracts.auth import SignUpContract, SignInContract
from models.user import User

class AuthController(Controller):
    prefix = "/auth"

    @POST("/signup")
    async def signup(self, ctx, contract: SignUpContract):
        """Register a new user, hashing their password hash."""
        data = contract.validated_data
        
        # Verify if record exists
        existing = await User.objects.filter(email=data["email"]).first()
        if existing:
            return Response.json({"error": "Email is already taken"}, status=400)
            
        auth_manager = ctx.container.resolve(AuthManager)
        hashed = auth_manager.password_hasher.hash(data["password"])
        
        user = await User.objects.create(
            name=data["name"],
            email=data["email"],
            password_hash=hashed,
            is_active=True,
            roles="user"
        )
        return Response.json({"success": True, "user_id": str(user.id)})

    @POST("/login")
    async def login(self, ctx, contract: SignInContract):
        """Authenticate user credentials and issue security tokens."""
        data = contract.validated_data
        auth_manager = ctx.container.resolve(AuthManager)
        
        user = await User.objects.filter(email=data["email"]).first()
        if not user or not user.is_active:
            return Response.json({"error": "Invalid credentials"}, status=401)
            
        # Initialize seed identity for dynamic stores
        identity = Identity(
            id=str(user.id),
            type=IdentityType.USER,
            attributes={
                "email": user.email,
                "name": user.name,
                "roles": user.roles.split(","),
            },
            status=IdentityStatus.ACTIVE,
        )
        
        try:
            # Complete login and return Issued Access and Refresh Tokens
            auth_result = await auth_manager.sign_in(
                username=user.email,
                password=data["password"],
                identity=identity,
            )
            return Response.json({
                "access_token": auth_result.access_token,
                "refresh_token": auth_result.refresh_token,
                "expires_in": auth_result.expires_in,
            })
        except Exception as e:
            return Response.json({"error": "Authentication failed"}, status=401)

    @GET("/profile")
    @authenticated
    async def profile(self, ctx, user: Identity):
        """Authenticated endpoint returns current user info."""
        return Response.json({
            "id": user.id,
            "name": user.get_attribute("name"),
            "email": user.get_attribute("email"),
            "roles": user.get_attribute("roles"),
        })

    @GET("/admin-panel")
    @roles_required("admin")
    async def admin_panel(self, ctx, user: Identity):
        """Admin restricted route."""
        return Response.json({"message": "Welcome, Administrator!"})
```



---

## Identity & Credentials
**URL**: `https://tubox.cloud/docs/auth/identity`

Security & Auth / Identity Identity & Credentials Deep dive into credential types — passwords (Argon2id), API keys (scoped, rate-limited), and how they map to the Identity frozen dataclass. Identity Methods Identity is a frozen dataclass — immutable after creation. It provides convenience methods for attribute access, permissions, and serialization. from aquilia.auth.core import Identity, IdentityType, IdentityStatus identity = Identity( id="user_42", type=IdentityType.USER, attributes= , status=IdentityStatus.ACTIVE, tenant_id="org_1", ) # Attribute access identity.get_attribute("email") # "alice@example.com" identity.get_attribute("missing") # None identity.get_attribute("missing", "default") # "default" # Role / scope checks identity.has_role("admin") # True identity.has_role("superadmin") # False identity.has_scope("read") # True identity.has_scope("admin:write") # True # Status checks identity.is_active() # True (ACTIVE) # Also checks: SUSPENDED → False, DELETED → False, PENDING → False # Serialization data = identity.to_dict() restored = Identity.from_dict(data) PasswordCredential The PasswordCredential manages authentication secrets for interactive users using modern hashing. from aquilia.auth.core import PasswordCredential cred = PasswordCredential( identity_id="user_42", password_hash="$argon2id$v=19$m=65536,t=3,p=4$...", algorithm="argon2id", # primary hasher must_change=False, ) # Check rotation policy (default: 90 days) if cred.should_rotate(max_age_days=90): # Prompt user to change password ... # Touch on successful login — updates last_used_at cred.touch() # Serialization data = cred.to_dict() ApiKeyCredential The ApiKeyCredential facilitates secure machine-to-machine client validations with customizable rate limits and scopes. from aquilia.auth.core import ApiKeyCredential # Key format: ak_ _ # Example: ak_live_1234567890abcdef key = ApiKeyCredential( identity_id="service_7", key_id="key_abc123", key_hash="sha256:...", # SHA-256 of the raw key prefix="ak_live_", # First 8 chars for identification scopes=["read:users", "write:orders"], rate_limit=100, # 100 requests per minute expires_at=None, # Never expires (or set a datetime) ) # Security checks key.is_expired() # False key.has_scope("read:users") # True # Keys are hashed before storage — raw key only shown once at creation Identity Types Aquilia natively supports different types of entities accessing the platform. Each type has specialized lifecycles and authentication workflows: , , , , ].map((item, i) => ( ))} Identity Status Status Meaning ))} )

### Code Examples
```python
from aquilia.auth.core import Identity, IdentityType, IdentityStatus

identity = Identity(
    id="user_42",
    type=IdentityType.USER,
    attributes={
        "email": "alice@example.com",
        "name": "Alice",
        "roles": ["admin", "editor"],
        "scopes": ["read", "write", "admin:write"],
    },
    status=IdentityStatus.ACTIVE,
    tenant_id="org_1",
)

# Attribute access
identity.get_attribute("email")      # "alice@example.com"
identity.get_attribute("missing")    # None
identity.get_attribute("missing", "default")  # "default"

# Role / scope checks
identity.has_role("admin")           # True
identity.has_role("superadmin")      # False
identity.has_scope("read")           # True
identity.has_scope("admin:write")    # True

# Status checks
identity.is_active()                 # True (ACTIVE)
# Also checks: SUSPENDED → False, DELETED → False, PENDING → False

# Serialization
data = identity.to_dict()
restored = Identity.from_dict(data)
```

```python
from aquilia.auth.core import PasswordCredential

cred = PasswordCredential(
    identity_id="user_42",
    password_hash="$argon2id$v=19$m=65536,t=3,p=4$...",
    algorithm="argon2id",          # primary hasher
    must_change=False,
)

# Check rotation policy (default: 90 days)
if cred.should_rotate(max_age_days=90):
    # Prompt user to change password
    ...

# Touch on successful login — updates last_used_at
cred.touch()

# Serialization
data = cred.to_dict()
```

```python
from aquilia.auth.core import ApiKeyCredential

# Key format: ak_<env>_<random>
# Example: ak_live_1234567890abcdef

key = ApiKeyCredential(
    identity_id="service_7",
    key_id="key_abc123",
    key_hash="sha256:...",          # SHA-256 of the raw key
    prefix="ak_live_",              # First 8 chars for identification
    scopes=["read:users", "write:orders"],
    rate_limit=100,                 # 100 requests per minute
    expires_at=None,                # Never expires (or set a datetime)
)

# Security checks
key.is_expired()     # False
key.has_scope("read:users")  # True

# Keys are hashed before storage — raw key only shown once at creation
```



---

## Credentials & Hashers
**URL**: `https://tubox.cloud/docs/auth/credentials`

Auth / Credentials & Hashers Credentials & Hashers Password hashing with Argon2id (primary) and PBKDF2 (fallback), password policy enforcement with HIBP breach checking, and async-safe convenience functions. PasswordHasher The PasswordHasher uses Argon2id as the primary algorithm with PBKDF2 as a fallback. All operations are async-safe — hashing runs in a thread executor to avoid blocking the event loop. from aquilia.auth.hashing import PasswordHasher hasher = PasswordHasher( algorithm="argon2id", # primary algorithm memory_cost=65536, # 64 MiB time_cost=3, # 3 iterations parallelism=4, # 4 threads hash_length=32, # 32-byte output salt_length=16, # 16-byte salt fallback_algorithm="pbkdf2",# PBKDF2-SHA256 fallback ) # Async hash and verify (runs in thread pool) hashed = await hasher.hash_async("MyP@ssw0rd!") is_valid = await hasher.verify_async("MyP@ssw0rd!", hashed) # → True # Rehash check — detects when params have changed if hasher.check_needs_rehash(hashed): new_hash = await hasher.hash_async(password) await credential_store.update_password(identity_id, new_hash) Convenience Functions from aquilia.auth.hashing import hash_password, verify_password, validate_password # Quick hash and verify (uses default PasswordHasher) hashed = hash_password("MyP@ssw0rd!") ok = verify_password("MyP@ssw0rd!", hashed) # Validate against policy (sync helper) is_valid, errors = validate_password("weak", policy) # is_valid → False # errors → ["Password must be at least 12 characters", ...] PasswordPolicy from aquilia.auth.hashing import PasswordPolicy policy = PasswordPolicy( min_length=12, # minimum 12 characters require_uppercase=True, # at least one A-Z require_lowercase=True, # at least one a-z require_digit=True, # at least one 0-9 require_special=True, # at least one special char check_breached=True, # HIBP breach check ) # Validate — async because breach check calls HIBP API is_valid, errors = await policy.validate_async("MyP@ssw0rd!") if not is_valid: print(errors) # → ["Password has been found in data breaches"] HIBP k-Anonymity: Only the first 5 characters of the SHA-1 hash are sent to the HIBP API. The full hash is never transmitted — the response is checked locally using range queries. Hasher Parameters Parameter Default Description ))} Other Credential Types , , ].map((c, i) => ( ))} )

### Code Examples
```python
from aquilia.auth.hashing import PasswordHasher

hasher = PasswordHasher(
    algorithm="argon2id",       # primary algorithm
    memory_cost=65536,          # 64 MiB
    time_cost=3,                # 3 iterations
    parallelism=4,              # 4 threads
    hash_length=32,             # 32-byte output
    salt_length=16,             # 16-byte salt
    fallback_algorithm="pbkdf2",# PBKDF2-SHA256 fallback
)

# Async hash and verify (runs in thread pool)
hashed = await hasher.hash_async("MyP@ssw0rd!")
is_valid = await hasher.verify_async("MyP@ssw0rd!", hashed)  # → True

# Rehash check — detects when params have changed
if hasher.check_needs_rehash(hashed):
    new_hash = await hasher.hash_async(password)
    await credential_store.update_password(identity_id, new_hash)
```

```python
from aquilia.auth.hashing import hash_password, verify_password, validate_password

# Quick hash and verify (uses default PasswordHasher)
hashed = hash_password("MyP@ssw0rd!")
ok = verify_password("MyP@ssw0rd!", hashed)

# Validate against policy (sync helper)
is_valid, errors = validate_password("weak", policy)
# is_valid  → False
# errors    → ["Password must be at least 12 characters", ...]
```

```python
from aquilia.auth.hashing import PasswordPolicy

policy = PasswordPolicy(
    min_length=12,                # minimum 12 characters
    require_uppercase=True,       # at least one A-Z
    require_lowercase=True,       # at least one a-z
    require_digit=True,           # at least one 0-9
    require_special=True,         # at least one special char
    check_breached=True,          # HIBP breach check
)

# Validate — async because breach check calls HIBP API
is_valid, errors = await policy.validate_async("MyP@ssw0rd!")
if not is_valid:
    print(errors)
    # → ["Password has been found in data breaches"]
```



---

## AuthManager
**URL**: `https://tubox.cloud/docs/auth/manager`

Security & Auth AuthManager The AuthManager is the central coordinator for all authentication operations. It orchestrates identity verification, token issuance, password hashing, rate limiting, and session management. Architecture AuthManager Orchestration AuthManager Central Coordinator , , , , , ].map((b, i) => ( ))} OPERATIONS , , , , ].map((op, i) => ( ))} Constructor from aquilia.auth import ( AuthManager, RateLimiter, PasswordHasher, TokenManager, TokenConfig, KeyRing, KeyDescriptor, KeyAlgorithm, MemoryIdentityStore, MemoryCredentialStore, MemoryTokenStore, ) # 1. Stores identity_store = MemoryIdentityStore() credential_store = MemoryCredentialStore() token_store = MemoryTokenStore() # 2. Key ring (one active signing key) key = KeyDescriptor.generate(kid="k1", algorithm=KeyAlgorithm.RS256) key_ring = KeyRing(keys=[key]) # 3. Token manager token_manager = TokenManager( key_ring=key_ring, token_store=token_store, config=TokenConfig( issuer="my-app", audience=["api"], access_token_ttl=3600, # 1 hour refresh_token_ttl=2592000, # 30 days ), ) # 4. Auth manager auth = AuthManager( identity_store=identity_store, credential_store=credential_store, token_manager=token_manager, password_hasher=PasswordHasher(), # Argon2id (auto-fallback to PBKDF2) rate_limiter=RateLimiter( max_attempts=5, window_seconds=900, # 15 min window lockout_duration=3600, # 1 hour lockout ), ) Parameter Type Description ))} Password Authentication result = await auth.authenticate_password( username="alice@example.com", # looked up by email then username password="SuperSecret!23", scopes=["profile", "orders.read"], session_id=None, # auto-generated if omitted client_metadata= , ) # AuthResult fields result.identity # Identity object result.access_token # Signed JWT (header.payload.signature) result.refresh_token # Opaque rt_ result.session_id # sess_ result.expires_in # 3600 (seconds) Password Auth Flow , , , , , , ].map((step, i) => ( ))} API Key Authentication result = await auth.authenticate_api_key( api_key="ak_live_abc123def456...", required_scopes=["orders.read"], # optional scope enforcement ) # API key IS the token — no separate JWT issued result.access_token # == api_key result.refresh_token # None result.session_id # None result.metadata # Token Refresh # Refresh token rotation (security best practice) new_access, new_refresh = await auth.refresh_access_token( refresh_token="rt_old_token_here" ) # The old refresh token is REVOKED after use # This prevents replay attacks # Verify & decode an access token claims = await auth.verify_token(access_token) # TokenClaims(iss, sub, aud, exp, iat, nbf, jti, scopes, roles, sid, tenant_id) # Get identity directly from token identity = await auth.get_identity_from_token(access_token) # Returns None if token is invalid/expired Revocation & Logout # Revoke a single token await auth.revoke_token("rt_abc...", token_type="refresh") await auth.revoke_token(access_jwt, token_type="access") # extracts JTI # Logout — revoke everything for user or session await auth.logout(identity_id="user_42") await auth.logout(session_id="sess_abc123") Rate Limiter The built-in RateLimiter prevents brute-force password attacks with a sliding window and automatic lockout. from aquilia.auth import RateLimiter limiter = RateLimiter( max_attempts=5, # failures before lockout window_seconds=900, # 15-minute sliding window lockout_duration=3600, # 1-hour lockout ) # Record a failed attempt limiter.record_attempt("auth:password:alice@example.com") Parameter Default Description ))} Authentication Faults AuthManager raises structured Fault exceptions integrated with AquilaFaults. Fault Code When Raised ))} DI Integration AuthManager is available as a DI provider via AuthManagerProvider. All dependencies are resolved automatically. from aquilia.auth.integration.di_providers import ( AuthManagerProvider, IdentityStoreProvider, CredentialStoreProvider, ) )

### Code Examples
```python
from aquilia.auth import (
    AuthManager, RateLimiter, PasswordHasher,
    TokenManager, TokenConfig, KeyRing, KeyDescriptor, KeyAlgorithm,
    MemoryIdentityStore, MemoryCredentialStore, MemoryTokenStore,
)

# 1. Stores
identity_store  = MemoryIdentityStore()
credential_store = MemoryCredentialStore()
token_store     = MemoryTokenStore()

# 2. Key ring (one active signing key)
key = KeyDescriptor.generate(kid="k1", algorithm=KeyAlgorithm.RS256)
key_ring = KeyRing(keys=[key])

# 3. Token manager
token_manager = TokenManager(
    key_ring=key_ring,
    token_store=token_store,
    config=TokenConfig(
        issuer="my-app",
        audience=["api"],
        access_token_ttl=3600,      # 1 hour
        refresh_token_ttl=2592000,   # 30 days
    ),
)

# 4. Auth manager
auth = AuthManager(
    identity_store=identity_store,
    credential_store=credential_store,
    token_manager=token_manager,
    password_hasher=PasswordHasher(),          # Argon2id (auto-fallback to PBKDF2)
    rate_limiter=RateLimiter(
        max_attempts=5,
        window_seconds=900,     # 15 min window
        lockout_duration=3600,  # 1 hour lockout
    ),
)
```

```python
result = await auth.authenticate_password(
    username="alice@example.com",     # looked up by email then username
    password="SuperSecret!23",
    scopes=["profile", "orders.read"],
    session_id=None,                  # auto-generated if omitted
    client_metadata={"ip": "1.2.3.4", "user_agent": "Chrome/120"},
)

# AuthResult fields
result.identity          # Identity object
result.access_token      # Signed JWT (header.payload.signature)
result.refresh_token     # Opaque rt_<random>
result.session_id        # sess_<random>
result.expires_in        # 3600 (seconds)
```

```python
result = await auth.authenticate_api_key(
    api_key="ak_live_abc123def456...",
    required_scopes=["orders.read"],  # optional scope enforcement
)

# API key IS the token — no separate JWT issued
result.access_token   # == api_key
result.refresh_token  # None
result.session_id     # None
result.metadata       # {"auth_method": "api_key", "key_id": "...", "scopes": [...]}
```



---

## OAuth2 / OIDC
**URL**: `https://tubox.cloud/docs/auth/oauth`

Security & Auth OAuth2 / OIDC The OAuth2Manager implements a complete OAuth 2.0 / OpenID Connect authorization server supporting Authorization Code (with PKCE), Client Credentials, Device Authorization, and Refresh Token flows. Supported Grant Types , , , , ].map((flow, i) => ( ))} OAuthClient Model from aquilia.auth.core import OAuthClient client = OAuthClient( client_id="app_my-frontend", client_secret_hash=OAuthClient.hash_client_secret("s3cr3t"), # SHA-256 name="My Frontend App", grant_types=["authorization_code", "refresh_token"], redirect_uris=["https://myapp.com/callback"], scopes=["profile", "orders.read", "orders.write"], require_pkce=True, # Enforce PKCE (default) require_consent=True, # Show consent screen (default) token_endpoint_auth_method="client_secret_post", access_token_ttl=3600, # 1 hour refresh_token_ttl=2592000, # 30 days ) Field Type Description ))} PKCE (Proof Key for Code Exchange) PKCE prevents authorization code interception. The client generates a code_verifier, sends a SHA-256 hash as code_challenge, then proves possession at token exchange. from aquilia.auth.oauth import PKCEVerifier # 1. Client generates verifier (43-128 chars) verifier = PKCEVerifier.generate_code_verifier(length=128) # 2. Client computes challenge challenge = PKCEVerifier.generate_code_challenge(verifier, method="S256") # 3. Server verifies at token exchange is_valid = PKCEVerifier.verify_code_challenge(verifier, challenge, method="S256") # True — constant-time comparison via secrets.compare_digest Authorization Code Flow ))} from aquilia.auth.oauth import OAuth2Manager oauth = OAuth2Manager( client_store=client_store, code_store=code_store, device_store=device_store, token_manager=token_manager, issuer="https://auth.myapp.com", ) # Step 1: Authorization request auth_request = await oauth.authorize( client_id="app_my-frontend", redirect_uri="https://myapp.com/callback", scope="profile orders.read", state="random-csrf-token", code_challenge=challenge, code_challenge_method="S256", ) Client Credentials Flow # Machine-to-machine auth — no user involved tokens = await oauth.client_credentials_grant( client_id="app_backend-service", client_secret="service-secret", scope="internal.admin", ) Device Authorization Flow # Step 1: Device requests authorization device_resp = await oauth.device_authorization( client_id="app_tv-app", scope="profile", ) OAuth Faults Fault Code When Raised ))} OAuth Stores OAuth2Manager requires stores for client data, authorization codes, and device verification tokens. Store Purpose ))} )

### Code Examples
```python
from aquilia.auth.core import OAuthClient

client = OAuthClient(
    client_id="app_my-frontend",
    client_secret_hash=OAuthClient.hash_client_secret("s3cr3t"),  # SHA-256
    name="My Frontend App",
    grant_types=["authorization_code", "refresh_token"],
    redirect_uris=["https://myapp.com/callback"],
    scopes=["profile", "orders.read", "orders.write"],
    require_pkce=True,           # Enforce PKCE (default)
    require_consent=True,        # Show consent screen (default)
    token_endpoint_auth_method="client_secret_post",
    access_token_ttl=3600,       # 1 hour
    refresh_token_ttl=2592000,   # 30 days
)
```

```python
from aquilia.auth.oauth import PKCEVerifier

# 1. Client generates verifier (43-128 chars)
verifier  = PKCEVerifier.generate_code_verifier(length=128)

# 2. Client computes challenge
challenge = PKCEVerifier.generate_code_challenge(verifier, method="S256")

# 3. Server verifies at token exchange
is_valid  = PKCEVerifier.verify_code_challenge(verifier, challenge, method="S256")
# True — constant-time comparison via secrets.compare_digest
```

```python
from aquilia.auth.oauth import OAuth2Manager

oauth = OAuth2Manager(
    client_store=client_store,
    code_store=code_store,
    device_store=device_store,
    token_manager=token_manager,
    issuer="https://auth.myapp.com",
)

# Step 1: Authorization request
auth_request = await oauth.authorize(
    client_id="app_my-frontend",
    redirect_uri="https://myapp.com/callback",
    scope="profile orders.read",
    state="random-csrf-token",
    code_challenge=challenge,
    code_challenge_method="S256",
)
```



---

## Multi-Factor Authentication
**URL**: `https://tubox.cloud/docs/auth/mfa`

Security & Auth Multi-Factor Authentication AquilAuth provides a complete MFA system with TOTPProvider (Google Authenticator compatible), WebAuthnProvider (FIDO2 / passkeys), backup recovery codes, and a unified MFAManager. Supported Methods , , , , ].map((m, i) => ( ))} MFACredential Model from aquilia.auth.core import MFACredential, CredentialStatus cred = MFACredential( identity_id="user_42", mfa_type="totp", # totp | webauthn | sms | email mfa_secret="JBSWY3DPEHPK3PXP", # Base32 TOTP secret backup_codes=["hash1", "hash2"], # SHA-256 hashed backup codes webauthn_credentials=[], # FIDO2 public key objects phone_number=None, # For SMS OTP email=None, # For email OTP status=CredentialStatus.ACTIVE, ) TOTP Provider from aquilia.auth.mfa import TOTPProvider totp = TOTPProvider( issuer="Aquilia", # Shown in authenticator app digits=6, # Code length (default 6) period=30, # Seconds per code (default 30) algorithm="SHA1", # SHA1 | SHA256 | SHA512 ) Backup Recovery Codes # Generate 10 backup codes (format: XXXX-XXXX-XXXX) codes = totp.generate_backup_codes(count=10) WebAuthn / FIDO2 from aquilia.auth.mfa import WebAuthnProvider webauthn = WebAuthnProvider( rp_id="myapp.com", # Relying Party ID (domain) rp_name="My Application", # Display name origin="https://myapp.com", # Expected origin ) MFAManager The MFAManager coordinates all MFA providers and handles enrollment and verification workflows. from aquilia.auth.mfa import MFAManager, TOTPProvider, WebAuthnProvider mfa = MFAManager( totp_provider=TOTPProvider(issuer="MyApp"), webauthn_provider=WebAuthnProvider( rp_id="myapp.com", rp_name="My App", origin="https://myapp.com", ), ) MFA + Password Authentication When MFA is enrolled, AuthManager.authenticate_password() raises AUTH_MFA_REQUIRED instead of returning tokens. from aquilia.auth import AuthManager, AUTH_MFA_REQUIRED try: result = await auth.authenticate_password( username="alice@example.com", password="SuperSecret!23", ) except AUTH_MFA_REQUIRED as e: # MFA enrolled — verify code separately pass MFA Faults Fault Code Description ))} )

### Code Examples
```python
from aquilia.auth.core import MFACredential, CredentialStatus

cred = MFACredential(
    identity_id="user_42",
    mfa_type="totp",                   # totp | webauthn | sms | email
    mfa_secret="JBSWY3DPEHPK3PXP",    # Base32 TOTP secret
    backup_codes=["hash1", "hash2"],   # SHA-256 hashed backup codes
    webauthn_credentials=[],           # FIDO2 public key objects
    phone_number=None,                 # For SMS OTP
    email=None,                        # For email OTP
    status=CredentialStatus.ACTIVE,
)
```

```python
from aquilia.auth.mfa import TOTPProvider

totp = TOTPProvider(
    issuer="Aquilia",     # Shown in authenticator app
    digits=6,             # Code length (default 6)
    period=30,            # Seconds per code (default 30)
    algorithm="SHA1",     # SHA1 | SHA256 | SHA512
)
```

```python
# Generate 10 backup codes (format: XXXX-XXXX-XXXX)
codes = totp.generate_backup_codes(count=10)
```



---

## Token Management
**URL**: `https://tubox.cloud/docs/auth/tokens`

Security & Auth Token Management AquilAuth's token system handles JWT-like access token signing/verification, opaque refresh tokens, key ring management with rotation, and multiple signing algorithms (HS256/HS384/HS512, RS256, ES256, EdDSA). HS256 is the zero-dependency default — RS256/ES256/EdDSA require pip install cryptography. Key Management KeyDescriptor from aquilia.auth.tokens import KeyDescriptor, KeyAlgorithm, KeyStatus # Generate a new key pair. Defaults to HS256 (stdlib only, zero deps) # when algorithm= is omitted; asymmetric algorithms need cryptography. key = KeyDescriptor.generate( kid="key_2024_01", # Key ID (used in JWT header) algorithm=KeyAlgorithm.RS256, # HS256 (default) | HS384 | HS512 | RS256 | ES256 | EdDSA ) # KeyDescriptor( # kid="key_2024_01", # algorithm="RS256", # public_key_pem="-----BEGIN PUBLIC KEY-----...", # private_key_pem="-----BEGIN PRIVATE KEY-----...", # status="active", # created_at=datetime(...), # ) # Key status lifecycle key.is_active() # True — can sign AND verify key.can_verify() # True for ACTIVE, ROTATING, RETIRED key.status # KeyStatus.ACTIVE # Serialization data = key.to_dict() # Dict with PEM keys key2 = KeyDescriptor.from_dict(data) Algorithm Key Type Description ))} Key Lifecycle Status Can Sign Can Verify Description ))} KeyRing & Rotation from aquilia.auth.tokens import KeyRing, KeyDescriptor, KeyAlgorithm from pathlib import Path # Create ring with initial key key1 = KeyDescriptor.generate(kid="k1", algorithm=KeyAlgorithm.ES256) ring = KeyRing(keys=[key1]) ring.current_kid # "k1" ring.get_signing_key() # KeyDescriptor (active) ring.get_verification_key("k1") # KeyDescriptor (if can_verify) # Key Rotation key2 = KeyDescriptor.generate(kid="k2", algorithm=KeyAlgorithm.ES256) ring.add_key(key2) # Add new key (ACTIVE by default) ring.promote_key("k2") # k2 → ACTIVE, k1 → RETIRED # k1 can still VERIFY (existing tokens remain valid) # k2 is now the SIGNING key ring.current_kid # "k2" # Revoke compromised key ring.revoke_key("k1") # k1 → REVOKED (can't verify anymore) # Persistence ring.to_file(Path("keys.json")) # Save to disk ring2 = KeyRing.from_file(Path("keys.json")) # Load from disk # Serialization data = ring.to_dict() ring3 = KeyRing.from_dict(data) TokenManager from aquilia.auth.tokens import TokenManager, TokenConfig, KeyRing # TokenConfig does NOT configure the signing algorithm -- that's a property # of the active KeyDescriptor inside the KeyRing you pass to TokenManager. config = TokenConfig( issuer="aquilia", # iss claim audience=["api"], # aud claim access_token_ttl=3600, # 1 hour refresh_token_ttl=2592000, # 30 days ) manager = TokenManager( key_ring=ring, # ring's KeyDescriptor.algorithm decides HS256/RS256/... token_store=token_store, # TokenStore protocol config=config, ) Access Tokens (JWT) # Issue signed access token token = await manager.issue_access_token( identity_id="user_42", scopes=["profile", "orders.read"], roles=["admin"], session_id="sess_abc123", tenant_id="org_1", ttl=7200, # override TTL (2 hours) ) # Format: header.payload.signature # Header: (or RS256/ES256/EdDSA per your KeyRing) # Payload: # Validate access token — checks: # 1. Format (3 parts) # 2. Header (alg, kid) # 3. Signature (using KeyRing verification key) # 4. Expiration (exp Refresh Tokens # Refresh token rotation (security best practice) new_access, new_refresh = await manager.refresh_access_token(refresh) # 1. Validates old refresh token # 2. Revokes old refresh token (one-time use) # 3. Issues new access + refresh tokens # → Prevents replay attacks # Revocation await manager.revoke_token("rt_abc...") # Single token await manager.revoke_tokens_by_identity("user_42") # All user tokens await manager.revoke_tokens_by_session("sess_abc") # All session tokens TokenClaims Claim Type Description ))} TokenStore Protocol Token storage follows the TokenStore protocol. Two implementations are provided: MemoryTokenStore (dev/test) and RedisTokenStore (production). class TokenStore(Protocol): async def save_refresh_token(self, token_id, identity_id, scopes, expires_at, session_id=None) -> None: ... async def get_refresh_token(self, token_id) -> dict | None: ... async def revoke_refresh_token(self, token_id) -> None: ... async def revoke_tokens_by_identity(self, identity_id) -> None: ... async def revoke_tokens_by_session(self, session_id) -> None: ... async def is_token_revoked(self, token_id) -> bool: ... # Built-in implementations: # MemoryTokenStore — dict-based, for dev/testing # RedisTokenStore — Redis-backed with sorted sets, auto-expiry )

### Code Examples
```python
from aquilia.auth.tokens import KeyDescriptor, KeyAlgorithm, KeyStatus

# Generate a new key pair. Defaults to HS256 (stdlib only, zero deps)
# when algorithm= is omitted; asymmetric algorithms need cryptography.
key = KeyDescriptor.generate(
    kid="key_2024_01",                  # Key ID (used in JWT header)
    algorithm=KeyAlgorithm.RS256,       # HS256 (default) | HS384 | HS512 | RS256 | ES256 | EdDSA
)
# KeyDescriptor(
#   kid="key_2024_01",
#   algorithm="RS256",
#   public_key_pem="-----BEGIN PUBLIC KEY-----...",
#   private_key_pem="-----BEGIN PRIVATE KEY-----...",
#   status="active",
#   created_at=datetime(...),
# )

# Key status lifecycle
key.is_active()        # True — can sign AND verify
key.can_verify()       # True for ACTIVE, ROTATING, RETIRED
key.status             # KeyStatus.ACTIVE

# Serialization
data = key.to_dict()               # Dict with PEM keys
key2 = KeyDescriptor.from_dict(data)
```

```python
from aquilia.auth.tokens import KeyRing, KeyDescriptor, KeyAlgorithm
from pathlib import Path

# Create ring with initial key
key1 = KeyDescriptor.generate(kid="k1", algorithm=KeyAlgorithm.ES256)
ring = KeyRing(keys=[key1])

ring.current_kid                    # "k1"
ring.get_signing_key()              # KeyDescriptor (active)
ring.get_verification_key("k1")     # KeyDescriptor (if can_verify)

# Key Rotation
key2 = KeyDescriptor.generate(kid="k2", algorithm=KeyAlgorithm.ES256)
ring.add_key(key2)                  # Add new key (ACTIVE by default)
ring.promote_key("k2")             # k2 → ACTIVE, k1 → RETIRED

# k1 can still VERIFY (existing tokens remain valid)
# k2 is now the SIGNING key
ring.current_kid                    # "k2"

# Revoke compromised key
ring.revoke_key("k1")              # k1 → REVOKED (can't verify anymore)

# Persistence
ring.to_file(Path("keys.json"))    # Save to disk
ring2 = KeyRing.from_file(Path("keys.json"))  # Load from disk

# Serialization
data = ring.to_dict()
ring3 = KeyRing.from_dict(data)
```

```python
from aquilia.auth.tokens import TokenManager, TokenConfig, KeyRing

# TokenConfig does NOT configure the signing algorithm -- that's a property
# of the active KeyDescriptor inside the KeyRing you pass to TokenManager.
config = TokenConfig(
    issuer="aquilia",                   # iss claim
    audience=["api"],                   # aud claim
    access_token_ttl=3600,              # 1 hour
    refresh_token_ttl=2592000,          # 30 days
)

manager = TokenManager(
    key_ring=ring,                # ring's KeyDescriptor.algorithm decides HS256/RS256/...
    token_store=token_store,     # TokenStore protocol
    config=config,
)
```



---

## Stores & Persistence
**URL**: `https://tubox.cloud/docs/auth/stores`

Security & Auth Stores & Persistence AquilAuth uses protocol-based stores for identities, credentials, tokens, and OAuth data. Memory implementations are provided for development; swap in Redis or database-backed stores for production. Store Architecture , , , , ].map((s, i) => ( ))} IdentityStore Protocol class IdentityStore(Protocol): async def create(self, identity: Identity) -> None: ... async def get(self, identity_id: str) -> Identity | None: ... async def get_by_attribute(self, key: str, value: Any) -> Identity | None: ... async def update(self, identity: Identity) -> None: ... async def delete(self, identity_id: str) -> None: ... # soft delete async def list_by_tenant(self, tenant_id: str) -> list[Identity]: ... MemoryIdentityStore from aquilia.auth.stores import MemoryIdentityStore from aquilia.auth.core import Identity, IdentityType, IdentityStatus store = MemoryIdentityStore() # Create — auto-indexes string/int/bool attributes identity = Identity( id="user_42", type=IdentityType.USER, attributes= , tenant_id="org_1", ) await store.create(identity) CredentialStore Protocol class CredentialStore(Protocol): # Password credentials async def create_password(self, credential: PasswordCredential) -> None: ... async def get_password(self, identity_id: str) -> PasswordCredential | None: ... async def update_password(self, credential: PasswordCredential) -> None: ... OAuth Stores from aquilia.auth.stores import ( MemoryOAuthClientStore, MemoryAuthorizationCodeStore, MemoryDeviceCodeStore, ) RedisTokenStore (Production) For production deployments, RedisTokenStore provides fast revocation checks and automatic TTL-based cleanup. from aquilia.auth.stores import RedisTokenStore store = RedisTokenStore( redis_client=aioredis_client, # aioredis async client key_prefix="aquilauth:", # Redis key namespace ) )

### Code Examples
```python
class IdentityStore(Protocol):
    async def create(self, identity: Identity) -> None: ...
    async def get(self, identity_id: str) -> Identity | None: ...
    async def get_by_attribute(self, key: str, value: Any) -> Identity | None: ...
    async def update(self, identity: Identity) -> None: ...
    async def delete(self, identity_id: str) -> None: ...        # soft delete
    async def list_by_tenant(self, tenant_id: str) -> list[Identity]: ...
```

```python
from aquilia.auth.stores import MemoryIdentityStore
from aquilia.auth.core import Identity, IdentityType, IdentityStatus

store = MemoryIdentityStore()

# Create — auto-indexes string/int/bool attributes
identity = Identity(
    id="user_42", type=IdentityType.USER,
    attributes={"email": "alice@example.com", "roles": ["admin"]},
    tenant_id="org_1",
)
await store.create(identity)
```

```python
class CredentialStore(Protocol):
    # Password credentials
    async def create_password(self, credential: PasswordCredential) -> None: ...
    async def get_password(self, identity_id: str) -> PasswordCredential | None: ...
    async def update_password(self, credential: PasswordCredential) -> None: ...
```



---

## Auth Faults Reference
**URL**: `https://tubox.cloud/docs/auth/faults`

Security & Auth Auth Faults Reference Aquilia auth uses structured Fault objects for all error conditions. Each fault carries a domain, code, severity, public-safe message, and retryable flag — enabling consistent error handling across your application. Fault Structure from aquilia.auth.faults import ( Fault, # base class raise_auth_fault, # raise helper is_auth_fault, # type check helper ) # Every auth fault provides: class Fault: domain: str # e.g. "auth" code: str # e.g. "AUTH_001" severity: str # "critical" | "error" | "warning" message: str # internal message (log-safe) public_message: str # user-facing message retryable: bool # can the client retry? status_code: int # HTTP status code (401, 403, etc.) Authentication Faults Code Name Description Status Retry ))} Authorization Faults Code Name Description Status Retry ))} Credential Faults Code Name Description Status Retry ))} Session Faults Code Name Description Status Retry ))} OAuth Faults Code Name Description Status Retry ))} MFA Faults Code Name Description Status Retry ))} Handling Auth Faults from aquilia.auth.faults import is_auth_fault, Fault # In your route handler async def login(request): try: result = await auth_manager.authenticate_password( identifier="alice@example.com", password=request.body["password"], ) return json( ) except Fault as fault: # Generic auth fault response — always use public_message return json( , status=fault.status_code) )

### Code Examples
```python
from aquilia.auth.faults import (
    Fault,               # base class
    raise_auth_fault,    # raise helper
    is_auth_fault,       # type check helper
)

# Every auth fault provides:
class Fault:
    domain: str           # e.g. "auth"
    code: str             # e.g. "AUTH_001"
    severity: str         # "critical" | "error" | "warning"
    message: str          # internal message (log-safe)
    public_message: str   # user-facing message
    retryable: bool       # can the client retry?
    status_code: int      # HTTP status code (401, 403, etc.)
```

```python
from aquilia.auth.faults import is_auth_fault, Fault

# In your route handler
async def login(request):
    try:
        result = await auth_manager.authenticate_password(
            identifier="alice@example.com",
            password=request.body["password"],
        )
        return json({"token": result.tokens["access_token"]})
    except Fault as fault:
        # Generic auth fault response — always use public_message
        return json({
            "error": fault.public_message,
            "code": fault.code,
            "retryable": fault.retryable,
        }, status=fault.status_code)
```



---

## Guards & Decorators
**URL**: `https://tubox.cloud/docs/auth/guards`

Security & Auth Guards & Decorators Aquilia provides a unified, context-first endpoint protection suite consisting of **Route Decorators** (aquilia/auth/decorators.py) and composable **Stateless Guards** (aquilia/auth/guards.py). Controller Route Decorators Decorators run inside controller endpoints, resolving identities and session structures from active request scopes, injecting resolved parameters into the handler when they are requested. @authenticated Blocks requests lacking active authenticated identities. Can redirect browser clients if a login URL is configured. @roles_required Asserts specific roles (with support for inheritance via PermissionEngine ) on the active identity. @scopes_required Asserts specific OAuth scope capabilities on the identity. @optional_auth Resolves the identity if present but does not block anonymous clients. Injects identity or session into handler. from aquilia.auth.decorators import authenticated, roles_required, scopes_required, optional_auth @authenticated async def get_profile(ctx, user: Identity): # Principal is automatically resolved and injected return @authenticated(login_url="/login", redirect_if_html=True) async def dashboard(ctx, session: Session): # Web browsers get redirected to /login?next=/dashboard return @roles_required("admin") async def delete_user(ctx, identity: Identity): ... @scopes_required("reports:read", require_all=True) async def fetch_reports(ctx): ... Composable Stateless Guards Guards are stateless protocol classes implementing a check(ctx) method. Multiple guards can be composed on any handler or pipeline using the @requires decorator. , , , , ].map((g, i) => ( ))} from aquilia.auth.guards import requires, AuthGuard, RoleGuard, PolicyGuard from aquilia.auth.permissions import PermissionEngine permissions = PermissionEngine() permissions.register_policy("is_owner", lambda identity, resource: identity.id == resource.owner_id) class DocumentController(Controller): @requires(AuthGuard, RoleGuard("editor")) async def edit_document(self, ctx): ... @requires(AuthGuard(), PolicyGuard("is_owner", engine=permissions)) async def delete_document(self, ctx): ... &larr; Credentials Authorization &rarr; )

### Code Examples
```python
from aquilia.auth.decorators import authenticated, roles_required, scopes_required, optional_auth

@authenticated
async def get_profile(ctx, user: Identity):
    # Principal is automatically resolved and injected
    return {"user_id": user.id}

@authenticated(login_url="/login", redirect_if_html=True)
async def dashboard(ctx, session: Session):
    # Web browsers get redirected to /login?next=/dashboard
    return {"theme": session.get("theme")}

@roles_required("admin")
async def delete_user(ctx, identity: Identity):
    ...

@scopes_required("reports:read", require_all=True)
async def fetch_reports(ctx):
    ...
```

```python
from aquilia.auth.guards import requires, AuthGuard, RoleGuard, PolicyGuard
from aquilia.auth.permissions import PermissionEngine

permissions = PermissionEngine()
permissions.register_policy("is_owner", lambda identity, resource: identity.id == resource.owner_id)

class DocumentController(Controller):

    @requires(AuthGuard, RoleGuard("editor"))
    async def edit_document(self, ctx):
        ...

    @requires(AuthGuard(), PolicyGuard("is_owner", engine=permissions))
    async def delete_document(self, ctx):
        ...
```



---

## Integration & Middleware
**URL**: `https://tubox.cloud/docs/auth/integration`

Security & Auth Integration & Middleware The aquilia.auth.integration package wires authentication seamlessly into Aquilia's dependency injection container, request-response middleware pipelines, session subsystems, and flow graphs. Integration Components , , , , ].map((s, i) => ( ))} DI Providers Importing aquilia.auth.integration.di_providers exposes all auth services to the DI registry under @service(scope="app"). from aquilia.auth.integration.di_providers import * # Provider → Provides # ───────────────────────────────────────── # PasswordHasherProvider → PasswordHasher (Argon2id) # KeyRingProvider → KeyRing (auto-generates RS256 key) # TokenManagerProvider → TokenManager (15m access, 30d refresh) # RateLimiterProvider → RateLimiter (5 attempts, 15min lockout) # MemoryIdentityStoreProvider → IdentityStore (in-memory) # MemoryCredentialStoreProvider → CredentialStore (in-memory) # MemoryTokenStoreProvider → TokenStore (in-memory) # MemoryOAuthClientStoreProvider → OAuthClientStore (in-memory) # MemoryAuthCodeStoreProvider → AuthorizationCodeStore (in-memory) # MemoryDeviceCodeStoreProvider → DeviceCodeStore (in-memory) # AuthManagerProvider → AuthManager (full auth pipeline) # MFAManagerProvider → MFAManager (TOTP + backup codes) # OAuth2ManagerProvider → OAuth2Manager (all 4 grant types) # AuthzEngineProvider → AuthzEngine (RBAC + ABAC + scopes) # SessionEngineProvider → SessionEngine (auth sessions) # SessionAuthBridgeProvider → SessionAuthBridge (session ↔ auth) Customizing Providers Override standard providers in the container context. Dependent services like AuthManager resolve overrides automatically. from aquilia.di import Container container = Container() # Register custom database/cache storage implementations container.register(IdentityStore, MyDatabaseIdentityStore) container.register(TokenStore, RedisTokenStore(redis_client)) # Other default providers dynamically resolve with the overrides Auth Middleware Pipeline The AuthMiddleware performs request authentication sequentially in 6 structured phases: , , , , , , ].map((step, i) => ( ))} from aquilia.auth.middleware import AuthMiddleware app = Aquilia() # Main authentication middleware configured with pluggable backends app.use(AuthMiddleware( auth_manager=auth_manager, session_engine=session_engine, require_auth=False, # Opt-in manually using decorators backends=[ "aquilia.auth.backends.TokenBackend", "aquilia.auth.backends.SessionBackend", ] )) Flow Graph Integration Because the new stateless guards in aquilia.auth.guards implement the callable protocol (__call__), they can be inserted directly as nodes inside Aquilia flow pipelines without any adapters. Flow Graph Assembly from aquilia.flow import Flow from aquilia.auth.guards import AuthGuard, RoleGuard admin_flow = ( Flow("admin_pipeline") .then(AuthGuard()) .then(RoleGuard("admin")) .then(execute_admin_logic_node) ) AuthPrincipal & Session Bridge Extract user parameters, roles, and scope permissions dynamically from current session contexts: from aquilia.auth.integration.aquila_sessions import ( bind_identity, bind_token_claims, get_identity_id, get_roles, get_scopes, ) # Set bindings (executed during request intercept) bind_identity(session, identity) bind_token_claims(session, claims) # Resolve attributes inside handler user_id = get_identity_id(session) roles = get_roles(session) scopes = get_scopes(session) )

### Code Examples
```python
from aquilia.auth.integration.di_providers import *

# Provider                      → Provides
# ─────────────────────────────────────────
# PasswordHasherProvider         → PasswordHasher  (Argon2id)
# KeyRingProvider                → KeyRing          (auto-generates RS256 key)
# TokenManagerProvider           → TokenManager     (15m access, 30d refresh)
# RateLimiterProvider            → RateLimiter      (5 attempts, 15min lockout)
# MemoryIdentityStoreProvider    → IdentityStore    (in-memory)
# MemoryCredentialStoreProvider  → CredentialStore   (in-memory)
# MemoryTokenStoreProvider       → TokenStore        (in-memory)
# MemoryOAuthClientStoreProvider → OAuthClientStore  (in-memory)
# MemoryAuthCodeStoreProvider    → AuthorizationCodeStore (in-memory)
# MemoryDeviceCodeStoreProvider  → DeviceCodeStore   (in-memory)
# AuthManagerProvider            → AuthManager       (full auth pipeline)
# MFAManagerProvider             → MFAManager        (TOTP + backup codes)
# OAuth2ManagerProvider          → OAuth2Manager     (all 4 grant types)
# AuthzEngineProvider            → AuthzEngine       (RBAC + ABAC + scopes)
# SessionEngineProvider          → SessionEngine     (auth sessions)
# SessionAuthBridgeProvider      → SessionAuthBridge (session ↔ auth)
```

```python
from aquilia.di import Container

container = Container()

# Register custom database/cache storage implementations
container.register(IdentityStore, MyDatabaseIdentityStore)
container.register(TokenStore, RedisTokenStore(redis_client))

# Other default providers dynamically resolve with the overrides
```

```python
from aquilia.auth.middleware import AuthMiddleware

app = Aquilia()

# Main authentication middleware configured with pluggable backends
app.use(AuthMiddleware(
    auth_manager=auth_manager,
    session_engine=session_engine,
    require_auth=False,   # Opt-in manually using decorators
    backends=[
        "aquilia.auth.backends.TokenBackend",
        "aquilia.auth.backends.SessionBackend",
    ]
))
```



---

## Credentials, AuthManager, OAuth2 & MFA
**URL**: `https://tubox.cloud/docs/auth/advanced`

Auth / Advanced Credentials, AuthManager, OAuth2 & MFA Deep dive into AquilAuth's credential system, authentication manager, OAuth2/OIDC provider, and multi-factor authentication engine. Credential System Credentials are typed, status-tracked authenticators attached to an Identity. Aquilia supports multiple credential types per identity. from aquilia.auth import ( PasswordCredential, ApiKeyCredential, OAuthClient, MFACredential, CredentialStatus, ) # Password credential with policy enforcement password = PasswordCredential( identity_id="user_123", hash=hash_password("S3cur3Pa$$word!"), status=CredentialStatus.ACTIVE, ) # API key credential api_key = ApiKeyCredential( identity_id="user_123", key_hash=hash_key("ak_live_xxxxxxxxxxxx"), prefix="ak_live_", name="Production API Key", scopes=["read:articles", "write:articles"], expires_at=datetime(2025, 12, 31), status=CredentialStatus.ACTIVE, ) # MFA credential (TOTP) mfa = MFACredential( identity_id="user_123", method="totp", secret=generate_totp_secret(), backup_codes=generate_backup_codes(count=10), status=CredentialStatus.ACTIVE, ) Password Hashing & Policy from aquilia.auth import ( PasswordHasher, PasswordPolicy, hash_password, verify_password, validate_password, ) # Hash & verify hashed = hash_password("MyP@ssw0rd!") is_valid = verify_password("MyP@ssw0rd!", hashed) # → True # Custom hasher hasher = PasswordHasher( algorithm="argon2id", memory_cost=65536, time_cost=3, parallelism=4, ) # Password policy policy = PasswordPolicy( min_length=12, require_uppercase=True, require_lowercase=True, require_digit=True, require_special=True, max_repeated_chars=3, check_breached=True, # Check against breach database prevent_reuse=5, # Remember last 5 passwords ) result = validate_password("weak", policy) # result.valid → False # result.errors → ["Too short (min 12)", "Missing uppercase", ...] AuthManager The AuthManager orchestrates the full authentication flow: credential verification, token issuance, rate limiting, and audit events. from aquilia.auth import AuthManager, RateLimiter auth = AuthManager( identity_store=db_identity_store, credential_store=db_credential_store, token_manager=token_mgr, rate_limiter=RateLimiter( max_attempts=5, window_seconds=300, # 5 attempts per 5 minutes lockout_seconds=900, # 15-minute lockout ), ) # Authenticate with password result = await auth.authenticate_password( email="user@example.com", password="MyP@ssw0rd!", ) if result.success: access_token = result.tokens.access_token refresh_token = result.tokens.refresh_token identity = result.identity elif result.mfa_required: # MFA challenge challenge = result.mfa_challenge # → send challenge to client elif result.locked: # Account locked due to too many attempts retry_after = result.retry_after # seconds # Authenticate with API key result = await auth.authenticate_api_key("ak_live_xxxxxxxxxxxx") # Refresh tokens new_tokens = await auth.refresh(refresh_token) # Revoke tokens await auth.revoke(access_token) Token Management from aquilia.auth import TokenManager, TokenConfig, KeyRing, KeyAlgorithm # Configure token manager token_mgr = TokenManager( config=TokenConfig( access_token_ttl=3600, # 1 hour refresh_token_ttl=2592000, # 30 days issuer="https://api.example.com", audience="example-app", ), key_ring=KeyRing( algorithm=KeyAlgorithm.ES256, rotation_interval=86400 * 30, # Rotate every 30 days ), ) # Issue tokens claims = TokenClaims( sub="user_123", roles=["admin"], scopes=["read", "write"], ) tokens = await token_mgr.issue(claims) # Verify token verified = await token_mgr.verify(tokens.access_token) # verified.sub → "user_123" # verified.roles → ["admin"] # Key rotation (seamless — old keys remain valid) await token_mgr.rotate_keys() OAuth2 / OIDC Full OAuth 2.0 Authorization Server with PKCE, device flow, and OpenID Connect support. from aquilia.auth import OAuth2Manager, OAuthClient oauth = OAuth2Manager( auth_manager=auth, token_manager=token_mgr, consent_store=consent_store, ) # Register OAuth client client = OAuthClient( client_id="app_123", client_secret_hash=hash_secret("cs_xxxx"), name="My App", redirect_uris=["https://app.example.com/callback"], grant_types=["authorization_code", "refresh_token"], scopes=["openid", "profile", "email"], pkce_required=True, ) # Authorization code flow auth_url = oauth.authorize_url( client_id="app_123", redirect_uri="https://app.example.com/callback", scope="openid profile email", state=generate_state(), code_challenge=code_challenge, code_challenge_method="S256", ) # Token exchange tokens = await oauth.exchange_code( code=authorization_code, client_id="app_123", client_secret="cs_xxxx", redirect_uri="https://app.example.com/callback", code_verifier=code_verifier, ) Multi-Factor Authentication from aquilia.auth import MFAManager mfa = MFAManager(credential_store=db_credential_store) # Enroll TOTP enrollment = await mfa.enroll_totp(identity_id="user_123") # enrollment.secret → "JBSWY3DPEHPK3PXP" # enrollment.qr_uri → "otpauth://totp/Aquilia:user@..." # enrollment.backup_codes → ["12345678", "87654321", ...] # Verify TOTP code (during login) is_valid = await mfa.verify_totp( identity_id="user_123", code="123456", ) # Use backup code is_valid = await mfa.use_backup_code( identity_id="user_123", code="12345678", ) # Check enrollment status enrolled = await mfa.is_enrolled(identity_id="user_123") methods = await mfa.enrolled_methods(identity_id="user_123") # → ["totp"] Guards Authorization )

### Code Examples
```python
from aquilia.auth import (
    PasswordCredential,
    ApiKeyCredential,
    OAuthClient,
    MFACredential,
    CredentialStatus,
)

# Password credential with policy enforcement
password = PasswordCredential(
    identity_id="user_123",
    hash=hash_password("S3cur3Pa$$word!"),
    status=CredentialStatus.ACTIVE,
)

# API key credential
api_key = ApiKeyCredential(
    identity_id="user_123",
    key_hash=hash_key("ak_live_xxxxxxxxxxxx"),
    prefix="ak_live_",
    name="Production API Key",
    scopes=["read:articles", "write:articles"],
    expires_at=datetime(2025, 12, 31),
    status=CredentialStatus.ACTIVE,
)

# MFA credential (TOTP)
mfa = MFACredential(
    identity_id="user_123",
    method="totp",
    secret=generate_totp_secret(),
    backup_codes=generate_backup_codes(count=10),
    status=CredentialStatus.ACTIVE,
)
```

```python
from aquilia.auth import (
    PasswordHasher,
    PasswordPolicy,
    hash_password,
    verify_password,
    validate_password,
)

# Hash & verify
hashed = hash_password("MyP@ssw0rd!")
is_valid = verify_password("MyP@ssw0rd!", hashed)  # → True

# Custom hasher
hasher = PasswordHasher(
    algorithm="argon2id",
    memory_cost=65536,
    time_cost=3,
    parallelism=4,
)

# Password policy
policy = PasswordPolicy(
    min_length=12,
    require_uppercase=True,
    require_lowercase=True,
    require_digit=True,
    require_special=True,
    max_repeated_chars=3,
    check_breached=True,       # Check against breach database
    prevent_reuse=5,           # Remember last 5 passwords
)

result = validate_password("weak", policy)
# result.valid → False
# result.errors → ["Too short (min 12)", "Missing uppercase", ...]
```

```python
from aquilia.auth import AuthManager, RateLimiter

auth = AuthManager(
    identity_store=db_identity_store,
    credential_store=db_credential_store,
    token_manager=token_mgr,
    rate_limiter=RateLimiter(
        max_attempts=5,
        window_seconds=300,       # 5 attempts per 5 minutes
        lockout_seconds=900,      # 15-minute lockout
    ),
)

# Authenticate with password
result = await auth.authenticate_password(
    email="user@example.com",
    password="MyP@ssw0rd!",
)

if result.success:
    access_token = result.tokens.access_token
    refresh_token = result.tokens.refresh_token
    identity = result.identity
elif result.mfa_required:
    # MFA challenge
    challenge = result.mfa_challenge
    # → send challenge to client
elif result.locked:
    # Account locked due to too many attempts
    retry_after = result.retry_after  # seconds

# Authenticate with API key
result = await auth.authenticate_api_key("ak_live_xxxxxxxxxxxx")

# Refresh tokens
new_tokens = await auth.refresh(refresh_token)

# Revoke tokens
await auth.revoke(access_token)
```



---

## Authorization Engine
**URL**: `https://tubox.cloud/docs/authz`

Security & Auth / Authorization Authorization Engine Aquilia's authorization subsystem coordinates RBAC (Role-Based), ABAC (Attribute-Based), scope checks, and tenant isolation policies into a unified, high-performance evaluation coordinator named AuthzEngine . Decision Model Aquilia evaluates authorization requests using a tri-state decision model. This allows policies to explicitly permit access, explicitly deny access, or abstain to let downstream policies decide. , , , ].map((d, i) => ( ))} Context & Result Structures Authorization requests are represented by `AuthzContext`, which holds the security principal ( Identity ), resource ID, action, scopes, roles, attributes, and tenant ID. Evaluators produce `AuthzResult` objects: from aquilia.auth.authz import Decision, AuthzContext, AuthzResult # AuthzContext - Input parameters for evaluating policies ctx = AuthzContext( identity=current_identity, # The authenticated Identity object resource="orders:1234", # The resource being accessed action="delete", # Action name scopes=["orders:read", "orders:write"], # Scopes derived from JWT/Session roles=["editor"], # Roles attached to the principal tenant_id="tenant_company_a", # Tenant ID for isolation check attributes= , # Resource attributes for ABAC ) # AuthzResult - Output describing decision outcome result = AuthzResult( decision=Decision.ALLOW, reason="Identity is resource owner", policy_id="owner_only", ) Unified AuthzEngine The AuthzEngine aggregates all sub-engines. It provides explicit helper checks for scopes, roles, permissions, and tenant mismatches, as well as a sequential ABAC policy evaluation pipeline. Default Deny: If no policy explicitly returns ALLOW or DENY, the engine falls back to a secure default deny decision. from aquilia.auth.authz import AuthzEngine # Initialize with sub-engines engine = AuthzEngine(rbac=rbac_engine, abac=abac_engine) # Configure order of ABAC policy runs engine.set_policy_order(["owner_can_edit", "business_hours_only"]) # 1. Pipeline check: runs ABAC policies, returning first non-ABSTAIN result result = engine.check(ctx) # 2. Enforcement: raises AUTHZ_POLICY_DENIED on Decision.DENY engine.authorize(ctx, raise_on_deny=True) # 3. Direct checks (raise specific faults on authorization failure) engine.check_scope(ctx, required_scopes=["orders:write"]) # Raises AUTHZ_INSUFFICIENT_SCOPE engine.check_role(ctx, required_roles=["admin"]) # Raises AUTHZ_INSUFFICIENT_ROLE engine.check_permission(ctx, permission="orders:delete") # Raises AUTHZ_RESOURCE_FORBIDDEN engine.check_tenant(ctx, resource_tenant_id="tenant_b") # Raises AUTHZ_TENANT_MISMATCH # 4. Utilities: filter allowed actions for a resource permitted_actions = engine.list_permitted_actions( identity=current_user, resource="orders:1234", actions=["read", "write", "delete"] ) Guards Role-Based Access Control (RBAC) )

### Code Examples
```python
from aquilia.auth.authz import Decision, AuthzContext, AuthzResult

# AuthzContext - Input parameters for evaluating policies
ctx = AuthzContext(
    identity=current_identity,       # The authenticated Identity object
    resource="orders:1234",          # The resource being accessed
    action="delete",                 # Action name
    scopes=["orders:read", "orders:write"], # Scopes derived from JWT/Session
    roles=["editor"],                # Roles attached to the principal
    tenant_id="tenant_company_a",    # Tenant ID for isolation check
    attributes={"owner_id": "user_42"}, # Resource attributes for ABAC
)

# AuthzResult - Output describing decision outcome
result = AuthzResult(
    decision=Decision.ALLOW,
    reason="Identity is resource owner",
    policy_id="owner_only",
)
```

```python
from aquilia.auth.authz import AuthzEngine

# Initialize with sub-engines
engine = AuthzEngine(rbac=rbac_engine, abac=abac_engine)

# Configure order of ABAC policy runs
engine.set_policy_order(["owner_can_edit", "business_hours_only"])

# 1. Pipeline check: runs ABAC policies, returning first non-ABSTAIN result
result = engine.check(ctx)

# 2. Enforcement: raises AUTHZ_POLICY_DENIED on Decision.DENY
engine.authorize(ctx, raise_on_deny=True)

# 3. Direct checks (raise specific faults on authorization failure)
engine.check_scope(ctx, required_scopes=["orders:write"]) # Raises AUTHZ_INSUFFICIENT_SCOPE
engine.check_role(ctx, required_roles=["admin"])           # Raises AUTHZ_INSUFFICIENT_ROLE
engine.check_permission(ctx, permission="orders:delete")  # Raises AUTHZ_RESOURCE_FORBIDDEN
engine.check_tenant(ctx, resource_tenant_id="tenant_b")    # Raises AUTHZ_TENANT_MISMATCH

# 4. Utilities: filter allowed actions for a resource
permitted_actions = engine.list_permitted_actions(
    identity=current_user,
    resource="orders:1234",
    actions=["read", "write", "delete"]
)
```



---

## Role-Based Access Control
**URL**: `https://tubox.cloud/docs/authz/rbac`

Security & Auth / Authorization / RBAC Role-Based Access Control Aquilia's Role-Based Access Control is driven by the RBACEngine . It supports explicit role definitions, permission mapping, multi-level role inheritance, and cyclic role detection. How RBAC Works Roles group users together, and permissions specify what operations are allowed on resources. Rather than checking roles directly, developers map permissions to roles and check those permissions at the route or handler level. Role Inheritance: Sub-roles inherit all permissions of parent roles recursively. The hierarchy resolver automatically prevents cyclic reference errors. Role Definition & Inheritance Define roles and their hierarchies on the RBACEngine . In this example, the `admin` role inherits from `editor`, which in turn inherits from `guest`: from aquilia.auth.authz import RBACEngine rbac = RBACEngine() # 1. Define base permissions for 'guest' rbac.define_role("guest", permissions=["posts:read"]) # 2. Define 'editor' role, inheriting from 'guest' rbac.define_role("editor", permissions=["posts:write"], inherits=["guest"]) # 3. Define 'admin' role, inheriting from 'editor' rbac.define_role("admin", permissions=["posts:delete"], inherits=["editor"]) # Recursive permission checking guest_perms = rbac.get_permissions("guest") # editor_perms = rbac.get_permissions("editor") # admin_perms = rbac.get_permissions("admin") # Enforcing Permissions Permissions can be checked dynamically by supplying a list of roles belonging to the user. This is typically invoked by the AuthzEngine : # Checks if any of the user's active roles grant a specific permission has_access = rbac.check_permission(roles=["editor"], permission="posts:write") # True # Context-based validation from aquilia.auth.authz import AuthzContext ctx = AuthzContext(identity=user, resource="posts", action="delete", roles=["editor"]) result = rbac.check(ctx, permission="posts:delete") # Returns AuthzResult(decision=Decision.DENY, reason="No role has permission: posts:delete") Overview Attribute-Based Access Control (ABAC) )

### Code Examples
```python
from aquilia.auth.authz import RBACEngine

rbac = RBACEngine()

# 1. Define base permissions for 'guest'
rbac.define_role("guest", permissions=["posts:read"])

# 2. Define 'editor' role, inheriting from 'guest'
rbac.define_role("editor", permissions=["posts:write"], inherits=["guest"])

# 3. Define 'admin' role, inheriting from 'editor'
rbac.define_role("admin", permissions=["posts:delete"], inherits=["editor"])

# Recursive permission checking
guest_perms = rbac.get_permissions("guest")   # {"posts:read"}
editor_perms = rbac.get_permissions("editor") # {"posts:read", "posts:write"}
admin_perms = rbac.get_permissions("admin")   # {"posts:read", "posts:write", "posts:delete"}
```

```python
# Checks if any of the user's active roles grant a specific permission
has_access = rbac.check_permission(roles=["editor"], permission="posts:write") # True

# Context-based validation
from aquilia.auth.authz import AuthzContext
ctx = AuthzContext(identity=user, resource="posts", action="delete", roles=["editor"])

result = rbac.check(ctx, permission="posts:delete")
# Returns AuthzResult(decision=Decision.DENY, reason="No role has permission: posts:delete")
```



---

## Attribute-Based Access Control
**URL**: `https://tubox.cloud/docs/authz/abac`

Security & Auth / Authorization / ABAC Attribute-Based Access Control Attribute-Based Access Control enables access decisions based on resource metadata, user parameters, and environment context. In Aquilia, this is driven by the ABACEngine and `PolicyBuilder` helper utilities. Registering & Evaluating Policies ABAC policies are callables that accept an `AuthzContext` and return an `AuthzResult`. Policies are registered with unique IDs in the ABACEngine : from aquilia.auth.authz import ABACEngine, Decision, AuthzResult, AuthzContext abac = ABACEngine() # Define and register a custom policy def check_owner(ctx: AuthzContext) -> AuthzResult: if ctx.attributes.get("owner_id") == ctx.identity.id: return AuthzResult(Decision.ALLOW, reason="Identity matches resource owner") return AuthzResult(Decision.ABSTAIN, reason="Identity is not owner") abac.register_policy("owner_can_edit", check_owner) # Evaluate the policy against a context ctx = AuthzContext(identity=user, resource="posts:123", action="edit", attributes= ) result = abac.evaluate(ctx, policy_id="owner_can_edit") print(result.decision) # Decision.ALLOW (if user.id == "user_42") Built-in Policy Builders Aquilia includes a static class `PolicyBuilder` providing pre-packaged ABAC configurations for common security requirements: , , , ].map((item, idx) => ( ))} from aquilia.auth.authz import PolicyBuilder # 1. Owner-only check (looks up attribute in context.attributes) owner_policy = PolicyBuilder.owner_only(attribute="owner_id") # 2. Admin role or resource owner check admin_or_owner_policy = PolicyBuilder.admin_or_owner( admin_role="administrator", attribute="owner_id", ) # 3. Restrict access to business hours (9 AM - 5 PM UTC) business_hours_policy = PolicyBuilder.time_based(allowed_hours=(9, 17)) RBAC Declarative Policy DSL )

### Code Examples
```python
from aquilia.auth.authz import ABACEngine, Decision, AuthzResult, AuthzContext

abac = ABACEngine()

# Define and register a custom policy
def check_owner(ctx: AuthzContext) -> AuthzResult:
    if ctx.attributes.get("owner_id") == ctx.identity.id:
        return AuthzResult(Decision.ALLOW, reason="Identity matches resource owner")
    return AuthzResult(Decision.ABSTAIN, reason="Identity is not owner")

abac.register_policy("owner_can_edit", check_owner)

# Evaluate the policy against a context
ctx = AuthzContext(identity=user, resource="posts:123", action="edit", attributes={"owner_id": "user_42"})
result = abac.evaluate(ctx, policy_id="owner_can_edit")
print(result.decision)  # Decision.ALLOW (if user.id == "user_42")
```

```python
from aquilia.auth.authz import PolicyBuilder

# 1. Owner-only check (looks up attribute in context.attributes)
owner_policy = PolicyBuilder.owner_only(attribute="owner_id")

# 2. Admin role or resource owner check
admin_or_owner_policy = PolicyBuilder.admin_or_owner(
    admin_role="administrator",
    attribute="owner_id",
)

# 3. Restrict access to business hours (9 AM - 5 PM UTC)
business_hours_policy = PolicyBuilder.time_based(allowed_hours=(9, 17))
```



---

## Declarative Policy DSL
**URL**: `https://tubox.cloud/docs/authz/policies`

Security & Auth / Authorization / Policy DSL Declarative Policy DSL The `aquilia.auth.policy` module provides a declarative, resource-centric policy language. Define complex authorization logic by subclassing Policy and decorating methods with `@rule`. Defining Resource Policies Resource policies group access rules for a specific resource type together. A rule method must be named can_&#123;action&#125; and return a PolicyResult using Allow, Deny, or Abstain: from aquilia.auth.policy import Policy, Allow, Deny, Abstain, rule class PostPolicy(Policy): resource = "post" # Connects this policy to the "post" resource name @rule def can_read(self, identity, resource=None): # Open access to anyone for reading return Allow("Public resource") @rule def can_edit(self, identity, resource): # Allow if the identity is the author of the post if resource and resource.author_id == identity.id: return Allow("Author can edit") # Defer to other rules if the user is an admin if identity.has_role("admin"): return Abstain("Let admin rules decide") return Deny("Must be author or administrator") The Policy Registry Polices are registered with a PolicyRegistry . When evaluating a permission, the registry locates the appropriate policy based on the resource name and evaluates the matching can_&#123;action&#125; method: from aquilia.auth.policy import PolicyRegistry from post_policy import PostPolicy # Initialize registry and register the policy registry = PolicyRegistry() registry.register(PostPolicy()) # Evaluate access dynamically result = registry.evaluate( resource="post", action="edit", identity=current_identity, resource_obj=active_post ) print(result.decision) # Decision.ALLOW or Decision.DENY print(result.reason) # "Author can edit" or "Must be author or administrator" Rule Resolution Flow When `evaluate()` is called, the policy engine follows this order of operations: ` matching the action argument.' }, , , , ].map((item, idx) => ( ))} ABAC Sessions )

### Code Examples
```python
from aquilia.auth.policy import Policy, Allow, Deny, Abstain, rule

class PostPolicy(Policy):
    resource = "post" # Connects this policy to the "post" resource name

    @rule
    def can_read(self, identity, resource=None):
        # Open access to anyone for reading
        return Allow("Public resource")

    @rule
    def can_edit(self, identity, resource):
        # Allow if the identity is the author of the post
        if resource and resource.author_id == identity.id:
            return Allow("Author can edit")
        
        # Defer to other rules if the user is an admin
        if identity.has_role("admin"):
            return Abstain("Let admin rules decide")
            
        return Deny("Must be author or administrator")
```

```python
from aquilia.auth.policy import PolicyRegistry
from post_policy import PostPolicy

# Initialize registry and register the policy
registry = PolicyRegistry()
registry.register(PostPolicy())

# Evaluate access dynamically
result = registry.evaluate(
    resource="post",
    action="edit",
    identity=current_identity,
    resource_obj=active_post
)

print(result.decision) # Decision.ALLOW or Decision.DENY
print(result.reason)   # "Author can edit" or "Must be author or administrator"
```



---

## Session System
**URL**: `https://tubox.cloud/docs/sessions`

function SessionArchitecture() = useTheme() const isDark = theme === 'dark' return ( DETECTION Cookie/Header extraction RESOLUTION Store lookup by ID VERIFICATION TTL & Fingerprint checks DI BINDING Register request-scope MUTATION Route logic & Dirty flag COMMIT ID rotate & Save store ) } Security / Sessions / Overview Session System Aquilia provides an explicit, policy-driven session subsystem featuring cryptographically secure identifiers, pluggable storage backends, transport-agnostic delivery, and deep integration with the Dependency Injection (DI) system. Architecture Components The session subsystem consists of multiple decoupled interfaces working together to manage server-side user state: , , , , , , , , ].map((item, i) => ( ))} Core Data Primitives SessionID A SessionID does not encode any identity or timestamps (preventing info leaks). It has 256 bits of entropy and is encoded into a URL-safe Base64 string: from aquilia.sessions import SessionID # Generate a new cryptographic session ID sid = SessionID() print(str(sid)) # sess_A1b2C3d4E5f6G7h8... print(len(str(sid))) # 49 characters (5 prefix + 44 base64) # Reconstruct from string (enforces length & structure guards) sid2 = SessionID.from_string("sess_A1b2C3d4E5f6G7h8...") Session Object The Session is a dataclass storing session data. It uses custom dictionary tracking to detect when nested properties change, automatically flagging the session as dirty for persistence. from datetime import timedelta from aquilia.sessions import Session, SessionID, SessionScope, SessionFlag, SessionPrincipal # Session stores user-specific state session = Session( id=SessionID(), data= , scope=SessionScope.USER, flags= , ) # Dict-like access (triggers dirty tracking automatically) session["theme"] = "light" session["cart"].append( ) # Lifecycle checking session.touch() session.extend_expiry(ttl=timedelta(minutes=30)) print(session.is_expired()) # False # Bind principal identity (for audits and concurrency) principal = SessionPrincipal(kind="user", id="user_99", attributes= ) session.mark_authenticated(principal) print(session.is_dirty) # True (marks dirty on principal change or data mutation) Lifetimes & Boundaries SessionScope SessionScope defines the lifecycle and persistence rules. Ephemeral scopes reside in memory and do not write to persistent stores. Scope Requires Persistence Description ))} SessionFlag Flags provide fine-grained status indicators used by components to toggle locking, expiration rotation, and read-only status. Flag Behavior & Purpose ))} Quick Start Setup To enable sessions, register the session integration and declare policies on your Workspace builder in workspace.py: from datetime import timedelta from aquilia import Workspace from aquilia.sessions import SessionPolicy, PersistencePolicy, ConcurrencyPolicy, TransportPolicy # Configure the workspace with custom session 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() ) Inject and require sessions inside your controllers using decorators: from aquilia import Controller, Get, Post from aquilia.sessions import session, Session class ShoppingController(Controller): prefix = "/shop" @Get("/cart") @session.require() async def view_cart(self, ctx, session: Session): """Require an existing session.""" return ctx.json( ) @Post("/cart") @session.ensure() async def add_item(self, ctx, session: Session): """Creates session if missing, then writes item.""" body = await ctx.request.json() cart = session.get("cart", []) cart.append(body) session["cart"] = cart # Triggers dirty state return ctx.json( ) )

### Code Examples
```python
from aquilia.sessions import SessionID

# Generate a new cryptographic session ID
sid = SessionID()
print(str(sid))        # sess_A1b2C3d4E5f6G7h8...
print(len(str(sid)))  # 49 characters (5 prefix + 44 base64)

# Reconstruct from string (enforces length & structure guards)
sid2 = SessionID.from_string("sess_A1b2C3d4E5f6G7h8...")
```

```python
from datetime import timedelta
from aquilia.sessions import Session, SessionID, SessionScope, SessionFlag, SessionPrincipal

# Session stores user-specific state
session = Session(
    id=SessionID(),
    data={"cart": [], "theme": "dark"},
    scope=SessionScope.USER,
    flags={SessionFlag.AUTHENTICATED, SessionFlag.RENEWABLE},
)

# Dict-like access (triggers dirty tracking automatically)
session["theme"] = "light"
session["cart"].append({"product": "Gizmo", "qty": 1})

# Lifecycle checking
session.touch()
session.extend_expiry(ttl=timedelta(minutes=30))
print(session.is_expired())  # False

# Bind principal identity (for audits and concurrency)
principal = SessionPrincipal(kind="user", id="user_99", attributes={"roles": ["member"]})
session.mark_authenticated(principal)

print(session.is_dirty)  # True (marks dirty on principal change or data mutation)
```

```python
from datetime import timedelta
from aquilia import Workspace
from aquilia.sessions import SessionPolicy, PersistencePolicy, ConcurrencyPolicy, TransportPolicy

# Configure the workspace with custom session 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()
)
```



---

## Workspace & Manifest Integration
**URL**: `https://tubox.cloud/docs/sessions/integration`

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) => ( ))} )

### Code Examples
```python
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()
)
```

```python
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,
        )
    ]
)
```

```python
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
```



---

## SessionEngine
**URL**: `https://tubox.cloud/docs/sessions/engine`

Sessions / Engine SessionEngine The SessionEngine orchestrates the entire session lifecycle, running a deterministic 7-phase execution pipeline, validating timeouts, enforcing concurrency, and broadcasting events. Creating the Engine The engine binds a policy, a storage backend, and a transport adapter together. It is typically registered as a singleton in the dependency injection container. from aquilia.sessions import ( SessionEngine, SessionPolicyBuilder, MemoryStore, CookieTransport ) # 1. Build a policy policy = ( SessionPolicyBuilder() .web_defaults() # Setup web defaults first .lasting(hours=2) # Customize values afterward .build() ) # 2. Setup store and transport store = MemoryStore.web_optimized() transport = CookieTransport.for_web_browsers() # 3. Instantiate the engine engine = SessionEngine( policy=policy, store=store, transport=transport, ) The 7-Phase Lifecycle Every request is resolved and committed through a structured, multi-phase pipeline in the session middleware: , , , , , , , ].map((item, i) => ( Phase : ))} Core Lifecycle APIs resolve() Resolves a session from the request context. This executes phases 1–4 of the lifecycle. session = await engine.resolve(request, container) commit() Runs ID rotation, checks concurrency limits, and persists modifications. This executes phases 6–7. await engine.commit(session, response, privilege_changed=True) destroy() Wipes the session from store and deletes the cookie/header references. await engine.destroy(session, response) Concurrency Control The engine queries active sessions from the store to check concurrency constraints. This check is executed before the session is saved during commit. await engine.check_concurrency(session) # Governed by policy concurrency configurations: # - ConcurrencyPolicy.behavior_on_limit = "reject" # Raises SessionConcurrencyViolationFault # - ConcurrencyPolicy.behavior_on_limit = "evict_oldest" # Automatically deletes oldest session # - ConcurrencyPolicy.behavior_on_limit = "evict_all" # Deletes all other active sessions for user Observability & Event Hooking Observe session state changes by registering a callable event handler. The engine broadcasts events for loading, timeout, hijacking, rotation, and destruction: def my_observability_observer(event_data: dict): print(f"Session Event: (Policy= )") engine.on_event(my_observability_observer) # Sample event payload: # , # "request_path": "/auth/refresh", # "request_method": "POST", # "client_ip": "127.0.0.1" # } )

### Code Examples
```python
from aquilia.sessions import (
    SessionEngine, SessionPolicyBuilder,
    MemoryStore, CookieTransport
)

# 1. Build a policy
policy = (
    SessionPolicyBuilder()
    .web_defaults()  # Setup web defaults first
    .lasting(hours=2) # Customize values afterward
    .build()
)

# 2. Setup store and transport
store = MemoryStore.web_optimized()
transport = CookieTransport.for_web_browsers()

# 3. Instantiate the engine
engine = SessionEngine(
    policy=policy,
    store=store,
    transport=transport,
)
```

```python
session = await engine.resolve(request, container)
```

```python
await engine.commit(session, response, privilege_changed=True)
```



---

## Session Policies
**URL**: `https://tubox.cloud/docs/sessions/policies`

Sessions / Policies Session Policies A SessionPolicy defines the rules that govern session lifetimes, timeouts, rotation, concurrency, persistence, and network transport details. SessionPolicy Data Class The policy is constructed using three sub-policies: PersistencePolicy , ConcurrencyPolicy , and TransportPolicy . from datetime import timedelta from aquilia.sessions import SessionPolicy, PersistencePolicy, ConcurrencyPolicy, TransportPolicy policy = SessionPolicy( name="web", ttl=timedelta(hours=2), idle_timeout=timedelta(minutes=30), absolute_timeout=timedelta(hours=12), rotate_on_use=False, rotate_on_privilege_change=True, fingerprint_binding=True, scope="user", # Sub-policies persistence=PersistencePolicy( enabled=True, store_name="default", write_through=True, compress=False, ), concurrency=ConcurrencyPolicy( max_sessions_per_principal=5, behavior_on_limit="evict_oldest", # "reject" | "evict_oldest" | "evict_all" ), transport=TransportPolicy( adapter="cookie", cookie_name="aquilia_session", cookie_httponly=True, cookie_secure=True, cookie_samesite="lax", cookie_path="/", header_name="X-Session-ID", ), ) SessionPolicyBuilder (Fluent Interface) Use the fluent builder SessionPolicyBuilder to construct policies. Important: Call preset defaults first (such as .web_defaults() or .admin_defaults()), then chain your overrides. Calling presets at the end of the chain will override your custom values. from aquilia.sessions import SessionPolicyBuilder # Web application policy (Web defaults, custom TTL overrides) web_policy = ( SessionPolicyBuilder() .web_defaults() # Loads web defaults first .lasting(hours=2) # Then overrides lasting TTL .idle_timeout(minutes=30) .build() ) # API token policy (Header transport defaults, extended lasting time) api_policy = ( SessionPolicyBuilder() .api_defaults() # Loads API defaults first .lasting(hours=24) # Customize afterward .build() ) # Admin policy (Strict single-session limit, rotated on use, fingerprint bound) admin_policy = ( SessionPolicyBuilder() .admin_defaults() # Setup strict admin defaults first .lasting(hours=8) # Customize properties next .idle_timeout(minutes=15) .absolute_timeout(hours=12) .rotating_on_use() .with_fingerprint_binding() .max_concurrent(1) .build() ) Builder Methods Reference Method Description ))} Built-in Policy Presets Aquilia exports pre-configured policies to handle standard development, API, and administrative session constraints: from aquilia.sessions.policy import ( DEFAULT_USER_POLICY, # 7d TTL, 30m idle, cookie transport, max 5 concurrent API_TOKEN_POLICY, # 1h TTL, no idle, header transport ("X-API-Token") EPHEMERAL_POLICY, # Request-scoped, persistence disabled, cookie transport ADMIN_POLICY, # 8h TTL, 15m idle, 12h absolute, fingerprint, max 1 concurrent ) )

### Code Examples
```python
from datetime import timedelta
from aquilia.sessions import SessionPolicy, PersistencePolicy, ConcurrencyPolicy, TransportPolicy

policy = SessionPolicy(
    name="web",
    ttl=timedelta(hours=2),
    idle_timeout=timedelta(minutes=30),
    absolute_timeout=timedelta(hours=12),
    rotate_on_use=False,
    rotate_on_privilege_change=True,
    fingerprint_binding=True,
    scope="user",
    
    # Sub-policies
    persistence=PersistencePolicy(
        enabled=True,
        store_name="default",
        write_through=True,
        compress=False,
    ),
    concurrency=ConcurrencyPolicy(
        max_sessions_per_principal=5,
        behavior_on_limit="evict_oldest", # "reject" | "evict_oldest" | "evict_all"
    ),
    transport=TransportPolicy(
        adapter="cookie",
        cookie_name="aquilia_session",
        cookie_httponly=True,
        cookie_secure=True,
        cookie_samesite="lax",
        cookie_path="/",
        header_name="X-Session-ID",
    ),
)
```

```python
from aquilia.sessions import SessionPolicyBuilder

# Web application policy (Web defaults, custom TTL overrides)
web_policy = (
    SessionPolicyBuilder()
    .web_defaults()  # Loads web defaults first
    .lasting(hours=2) # Then overrides lasting TTL
    .idle_timeout(minutes=30)
    .build()
)

# API token policy (Header transport defaults, extended lasting time)
api_policy = (
    SessionPolicyBuilder()
    .api_defaults()  # Loads API defaults first
    .lasting(hours=24) # Customize afterward
    .build()
)

# Admin policy (Strict single-session limit, rotated on use, fingerprint bound)
admin_policy = (
    SessionPolicyBuilder()
    .admin_defaults()  # Setup strict admin defaults first
    .lasting(hours=8)  # Customize properties next
    .idle_timeout(minutes=15)
    .absolute_timeout(hours=12)
    .rotating_on_use()
    .with_fingerprint_binding()
    .max_concurrent(1)
    .build()
)
```

```python
from aquilia.sessions.policy import (
    DEFAULT_USER_POLICY,   # 7d TTL, 30m idle, cookie transport, max 5 concurrent
    API_TOKEN_POLICY,      # 1h TTL, no idle, header transport ("X-API-Token")
    EPHEMERAL_POLICY,      # Request-scoped, persistence disabled, cookie transport
    ADMIN_POLICY,          # 8h TTL, 15m idle, 12h absolute, fingerprint, max 1 concurrent
)
```



---

## Session Stores
**URL**: `https://tubox.cloud/docs/sessions/stores`

Sessions / Stores Session Stores Session stores manage persistence and loading of active sessions. Aquilia exposes a typed SessionStore protocol, implemented out-of-the-box by MemoryStore and FileStore. SessionStore Protocol All storage backends must implement the SessionStore protocol. Stores are purely responsible for persistence — they do not enforce expiration policies or idle timeouts. from typing import Protocol from aquilia.sessions import Session, SessionID class SessionStore(Protocol): """Protocol for session storage backends.""" async def load(self, session_id: SessionID) -> Session | None: """Load session by ID. Returns None if not found or corrupted.""" ... async def save(self, session: Session) -> None: """Persist session. Sets session version and resets dirty state.""" ... async def delete(self, session_id: SessionID) -> None: """Delete session by ID.""" ... async def exists(self, session_id: SessionID) -> bool: """Check if session exists in store.""" ... async def list_by_principal(self, principal_id: str) -> list[Session]: """Find active sessions belonging to user principal.""" ... async def count_by_principal(self, principal_id: str) -> int: """Count active sessions belonging to user principal.""" ... async def cleanup_expired(self) -> int: """Remove expired sessions from storage. Returns removed count.""" ... async def shutdown(self) -> None: """Gracefully release storage client resources.""" ... MemoryStore (In-Memory LRU) An in-memory store utilizing an OrderedDict to achieve O(1) LRU eviction. Features locking for asynchronous consistency and secondary index tables for principal queries. MemoryStore is not persistent across server reboots. from aquilia.sessions import MemoryStore # Manual construction (requires max_sessions limit) store = MemoryStore(max_sessions=10000) # Factory presets optimized for specific payloads: # Web: High capacity (25k max sessions) store = MemoryStore.web_optimized() # API: Medium capacity (15k max sessions) store = MemoryStore.api_optimized() # Mobile: Medium capacity (15k max sessions) store = MemoryStore.development_focused() # 1k capacity # High-throughput: Max capacity (50k max sessions) store = MemoryStore.high_throughput() LRU Eviction Mechanism When capacity is reached, new saves trigger LRU eviction, popping the oldest accessed session from the store: store = MemoryStore(max_sessions=3) # 1. Fill the store await store.save(session_a) # OrderedDict: [A] await store.save(session_b) # OrderedDict: [A, B] await store.save(session_c) # OrderedDict: [A, B, C] # 2. Access A to make it recently-used await store.load(session_a.id) # OrderedDict moves A to end: [B, C, A] # 3. Save D triggers LRU eviction of B await store.save(session_d) # OrderedDict evicts B: [C, A, D] print(await store.exists(session_b.id)) # False (evicted!) FileStore (JSON File-based) Saves each session as an individual JSON file. Incorporates atomic write protocols (temp file creation + atomic rename) to ensure file corruption does not occur during system failures. FileStore is suitable for low-traffic development. from aquilia.sessions import FileStore # Constructor takes directory folder path store = FileStore(directory="/var/lib/aquilia/sessions") # Session IDs are strictly validated to prevent path-traversal attacks. # Data is formatted inside sess_*.json files. Building a Custom Store (Redis Example) Implement the SessionStore protocol to define your custom storage (such as Redis, DynamoDB, or PostgreSQL): import json from datetime import datetime, timezone from aquilia.sessions import Session, SessionID class RedisSessionStore: """Pluggable Redis backend implementing SessionStore protocol.""" def __init__(self, client, prefix: str = "aquilia:sess:"): self.client = client self.prefix = prefix def _key(self, sid: SessionID) -> str: return f" " async def load(self, session_id: SessionID) -> Session | None: raw = await self.client.get(self._key(session_id)) if not raw: return None return Session.from_dict(json.loads(raw)) async def save(self, session: Session) -> None: key = self._key(session.id) payload = json.dumps(session.to_dict()) # Calculate remaining TTL seconds dynamically ttl = 3600 if session.expires_at: now = datetime.now(timezone.utc) ttl = max(int((session.expires_at - now).total_seconds()), 1) await self.client.setex(key, ttl, payload) # Keep track of principal query indices if session.principal: p_key = f" principal: " await self.client.sadd(p_key, str(session.id)) session.mark_clean() async def delete(self, session_id: SessionID) -> None: session = await self.load(session_id) key = self._key(session_id) await self.client.delete(key) if session and session.principal: p_key = f" principal: " await self.client.srem(p_key, str(session_id)) async def exists(self, session_id: SessionID) -> bool: return bool(await self.client.exists(self._key(session_id))) async def list_by_principal(self, principal_id: str) -> list[Session]: p_key = f" principal: " sids = await self.client.smembers(p_key) sessions = [] for sid_str in sids: try: sid = SessionID.from_string(sid_str) sess = await self.load(sid) if sess: sessions.append(sess) except Exception: continue return sessions async def count_by_principal(self, principal_id: str) -> int: p_key = f" principal: " return await self.client.scard(p_key) async def cleanup_expired(self) -> int: # No-op: Redis automatically evicts keys using setex TTLs return 0 async def shutdown(self) -> None: await self.client.close() # Register the store in the SessionEngine (engine receives a single store instance) from aquilia.sessions import SessionEngine engine = SessionEngine( policy=policy, store=RedisSessionStore(redis_client), transport=transport ) Store Comparison Feature MemoryStore FileStore Custom (Redis) ))} )

### Code Examples
```python
from typing import Protocol
from aquilia.sessions import Session, SessionID


class SessionStore(Protocol):
    """Protocol for session storage backends."""

    async def load(self, session_id: SessionID) -> Session | None:
        """Load session by ID. Returns None if not found or corrupted."""
        ...

    async def save(self, session: Session) -> None:
        """Persist session. Sets session version and resets dirty state."""
        ...

    async def delete(self, session_id: SessionID) -> None:
        """Delete session by ID."""
        ...

    async def exists(self, session_id: SessionID) -> bool:
        """Check if session exists in store."""
        ...

    async def list_by_principal(self, principal_id: str) -> list[Session]:
        """Find active sessions belonging to user principal."""
        ...

    async def count_by_principal(self, principal_id: str) -> int:
        """Count active sessions belonging to user principal."""
        ...

    async def cleanup_expired(self) -> int:
        """Remove expired sessions from storage. Returns removed count."""
        ...

    async def shutdown(self) -> None:
        """Gracefully release storage client resources."""
        ...
```

```python
from aquilia.sessions import MemoryStore

# Manual construction (requires max_sessions limit)
store = MemoryStore(max_sessions=10000)

# Factory presets optimized for specific payloads:

# Web: High capacity (25k max sessions)
store = MemoryStore.web_optimized()

# API: Medium capacity (15k max sessions)
store = MemoryStore.api_optimized()

# Mobile: Medium capacity (15k max sessions)
store = MemoryStore.development_focused()  # 1k capacity

# High-throughput: Max capacity (50k max sessions)
store = MemoryStore.high_throughput()
```

```python
store = MemoryStore(max_sessions=3)

# 1. Fill the store
await store.save(session_a) # OrderedDict: [A]
await store.save(session_b) # OrderedDict: [A, B]
await store.save(session_c) # OrderedDict: [A, B, C]

# 2. Access A to make it recently-used
await store.load(session_a.id) # OrderedDict moves A to end: [B, C, A]

# 3. Save D triggers LRU eviction of B
await store.save(session_d) # OrderedDict evicts B: [C, A, D]
print(await store.exists(session_b.id)) # False (evicted!)
```



---

## Session Transport
**URL**: `https://tubox.cloud/docs/sessions/transport`

Sessions / Transport Session Transport Transport layers manage how session identifiers travel over HTTP requests and responses. They isolate network details from session state using the SessionTransport protocol. SessionTransport Protocol All transport adapters implement the synchronous SessionTransport protocol: from typing import Protocol from aquilia.request import Request from aquilia.response import Response from aquilia.sessions import Session class SessionTransport(Protocol): """Protocol for session ID transport mechanisms (synchronous methods).""" def extract(self, request: Request) -> str | None: """Extract a session ID string from the incoming request.""" ... def inject(self, response: Response, session: Session) -> None: """Inject the session ID into the outgoing response.""" ... def clear(self, response: Response) -> None: """Remove the session ID from the outgoing response (on logout/destroy).""" ... CookieTransport (HTTP Cookies) Sends the session ID as an HTTP cookie. Highly recommended for web browsers as it provides HttpOnly (XSS block), Secure (HTTPS enforce), and SameSite (CSRF block) security parameters via CookieTransport . from aquilia.sessions import CookieTransport, TransportPolicy # Constructor accepts a TransportPolicy policy = TransportPolicy( adapter="cookie", cookie_name="aquilia_web_session", cookie_httponly=True, cookie_secure=True, cookie_samesite="strict", cookie_path="/", ) transport = CookieTransport(policy) # Factory methods for pre-configured defaults: transport_web = CookieTransport.for_web_browsers() transport_spa = CookieTransport.for_spa_applications() transport_mobile = CookieTransport.for_mobile_webviews() transport_default = CookieTransport.with_aquilia_defaults() HeaderTransport (Custom Headers) Transports the session ID using custom headers. Best suited for stateless REST APIs, mobile apps, or inter-service communications where cookies are difficult to handle, implemented via HeaderTransport . from aquilia.sessions import HeaderTransport, TransportPolicy # Constructor accepts a TransportPolicy policy = TransportPolicy(adapter="header", header_name="X-Session-ID") transport = HeaderTransport(policy) # Factory methods for pre-configured defaults: transport_rest = HeaderTransport.for_rest_apis() transport_graphql = HeaderTransport.for_graphql_apis() transport_mobile = HeaderTransport.for_mobile_apis() transport_service = HeaderTransport.for_microservices() transport_default = HeaderTransport.with_aquilia_defaults() create_transport() Factory Helper utility function to initialize transport adapters directly from policy configurations: from aquilia.sessions import create_transport, TransportPolicy policy = TransportPolicy(adapter="cookie", cookie_name="my_custom_cookie") transport = create_transport(policy) Building a Custom Transport Create custom transport layers (for example, reading token properties from custom JSON payloads or Authorization headers) by matching the protocol: from aquilia.request import Request from aquilia.response import Response from aquilia.sessions import Session class BearerTokenTransport: """Custom transport for extracting session IDs from the Authorization Bearer header.""" def extract(self, request: Request) -> str | None: auth = request.header("authorization") or "" if auth.startswith("Bearer "): return auth[7:] return None def inject(self, response: Response, session: Session) -> None: response.headers["Authorization"] = f"Bearer " def clear(self, response: Response) -> None: if "Authorization" in response.headers: del response.headers["Authorization"] )

### Code Examples
```python
from typing import Protocol
from aquilia.request import Request
from aquilia.response import Response
from aquilia.sessions import Session

class SessionTransport(Protocol):
    """Protocol for session ID transport mechanisms (synchronous methods)."""

    def extract(self, request: Request) -> str | None:
        """Extract a session ID string from the incoming request."""
        ...

    def inject(self, response: Response, session: Session) -> None:
        """Inject the session ID into the outgoing response."""
        ...

    def clear(self, response: Response) -> None:
        """Remove the session ID from the outgoing response (on logout/destroy)."""
        ...
```

```python
from aquilia.sessions import CookieTransport, TransportPolicy

# Constructor accepts a TransportPolicy
policy = TransportPolicy(
    adapter="cookie",
    cookie_name="aquilia_web_session",
    cookie_httponly=True,
    cookie_secure=True,
    cookie_samesite="strict",
    cookie_path="/",
)
transport = CookieTransport(policy)

# Factory methods for pre-configured defaults:
transport_web = CookieTransport.for_web_browsers()
transport_spa = CookieTransport.for_spa_applications()
transport_mobile = CookieTransport.for_mobile_webviews()
transport_default = CookieTransport.with_aquilia_defaults()
```

```python
from aquilia.sessions import HeaderTransport, TransportPolicy

# Constructor accepts a TransportPolicy
policy = TransportPolicy(adapter="header", header_name="X-Session-ID")
transport = HeaderTransport(policy)

# Factory methods for pre-configured defaults:
transport_rest = HeaderTransport.for_rest_apis()
transport_graphql = HeaderTransport.for_graphql_apis()
transport_mobile = HeaderTransport.for_mobile_apis()
transport_service = HeaderTransport.for_microservices()
transport_default = HeaderTransport.with_aquilia_defaults()
```



---

## Session Decorators
**URL**: `https://tubox.cloud/docs/sessions/decorators`

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` and `@scopes_required` from the authentication module: from aquilia.auth import authenticated, scopes_required from aquilia.sessions import session class OrderController(Controller): prefix = "/orders" @Get("/") @authenticated # Enforces authentication (auth module) @scopes_required("orders:read") # Enforces permission (auth module) async def list_orders(self, ctx, user): orders = await Order.objects.filter(user_id=user.id) return ctx.json([o.to_dict() for o in orders]) @Post("/") @session.require(authenticated=True) # Enforces session & auth @scopes_required("orders:write") # 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) )

### Code Examples
```python
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({
            "user": session.principal.id if session.principal else None,
            "theme": session.get("theme", "light"),
        })

    @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({"admin": True, "user": session.principal.id})
```

```python
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({"items": session.get("cart", [])})

    @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({"items": cart}, status=201)
```

```python
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({"product": product.to_dict(), "theme": theme})
```



---

## Typed Session State
**URL**: `https://tubox.cloud/docs/sessions/state`

Sessions / State Typed Session State The SessionState system provides type-safe, structured access to session dictionaries. By defining typed states with Field descriptors, you avoid raw string key access like session["key"]. SessionState Base Class Inheriting from SessionState enables typed field validation and default value seeding for session data dictionaries: from aquilia.sessions.state import SessionState, Field class MyState(SessionState): """Define typed fields that sync with session.data.""" # Field with a default value theme: str = Field(default="light") # Field with a factory (for mutable lists/dicts) cart_items: list = Field(default_factory=list) # Field with no default (returns None if missing from session data) user_name: str = Field() Field Descriptor The Field class acts as a Python descriptor governing access and mutations. It takes two configuration parameters: Parameter Type Description ))} How Synchronization Works Typed states wrap the session data dictionary directly. Instantiating a state pulls/pushes keys to the underlying dictionary, updating dirty markers: from aquilia.sessions import Session, SessionID from aquilia.sessions.state import SessionState, Field class CartState(SessionState): items: list = Field(default_factory=list) coupon: str = Field(default="") # 1. Create a session with existing data session = Session( id=SessionID(), data= ], "coupon": "SAVE20"}, ) # 2. Wrap the session data dictionary directly (no from_session classmethod exists) state = CartState(session.data) # 3. Read operations pull from session.data print(state.items) # [ ] print(state.coupon) # "SAVE20" # 4. Write operations push to session.data and mark the session dirty state.items.append( ) state.coupon = "SAVE30" print(session.data["items"]) # [ , ] print(session.data["coupon"]) # "SAVE30" print(session.is_dirty) # True (marked dirty automatically!) State Examples & Controller Binding CartState Integrate typed states into controllers using the bare @stateful decorator and a type-hinted state argument: from aquilia import Controller, Post from aquilia.sessions import stateful from aquilia.sessions.state import CartState class CartController(Controller): prefix = "/cart" # Use bare @stateful decorator. Do NOT pass CartState as argument. # The decorator inspects type-hints of the 'state' parameter. @Post("/add") @stateful async def add(self, ctx, state: CartState): product = await ctx.request.json() state.items.append(product) state.subtotal += product.get("price", 0.0) return ctx.json( ) UserPreferencesState from aquilia import Controller, Get, Post from aquilia.sessions import stateful from aquilia.sessions.state import UserPreferencesState class SettingsController(Controller): prefix = "/settings" @Get("/") @stateful async def get_prefs(self, ctx, state: UserPreferencesState): return ctx.json( ) @Post("/") @stateful async def update_prefs(self, ctx, state: UserPreferencesState): body = await ctx.request.json() if "theme" in body: state.theme = body["theme"] if "locale" in body: state.language = body["locale"] return ctx.json( ) )

### Code Examples
```python
from aquilia.sessions.state import SessionState, Field


class MyState(SessionState):
    """Define typed fields that sync with session.data."""
    
    # Field with a default value
    theme: str = Field(default="light")
    
    # Field with a factory (for mutable lists/dicts)
    cart_items: list = Field(default_factory=list)
    
    # Field with no default (returns None if missing from session data)
    user_name: str = Field()
```

```python
from aquilia.sessions import Session, SessionID
from aquilia.sessions.state import SessionState, Field


class CartState(SessionState):
    items: list = Field(default_factory=list)
    coupon: str = Field(default="")


# 1. Create a session with existing data
session = Session(
    id=SessionID(),
    data={"items": [{"id": 1, "name": "Widget"}], "coupon": "SAVE20"},
)

# 2. Wrap the session data dictionary directly (no from_session classmethod exists)
state = CartState(session.data)

# 3. Read operations pull from session.data
print(state.items)   # [{"id": 1, "name": "Widget"}]
print(state.coupon)  # "SAVE20"

# 4. Write operations push to session.data and mark the session dirty
state.items.append({"id": 2, "name": "Gadget"})
state.coupon = "SAVE30"

print(session.data["items"])   # [{"id": 1, ...}, {"id": 2, ...}]
print(session.data["coupon"])  # "SAVE30"
print(session.is_dirty)        # True (marked dirty automatically!)
```

```python
from aquilia import Controller, Post
from aquilia.sessions import stateful
from aquilia.sessions.state import CartState


class CartController(Controller):
    prefix = "/cart"
    
    # Use bare @stateful decorator. Do NOT pass CartState as argument.
    # The decorator inspects type-hints of the 'state' parameter.
    @Post("/add")
    @stateful
    async def add(self, ctx, state: CartState):
        product = await ctx.request.json()
        state.items.append(product)
        state.subtotal += product.get("price", 0.0)
        return ctx.json({
            "items": len(state.items),
            "subtotal": state.subtotal,
            "currency": state.currency,
        })
```



---

## Session Context
**URL**: `https://tubox.cloud/docs/sessions/guards`

Sessions / Context Session Context Manage scoped sessions inside code blocks using SessionContext context managers. Scoped Session Access with SessionContext The SessionContext manager provides scoped asynchronous context managers. They accept the request context (ctx) and handle startup resolution and shutdown commit/rollbacks: 1. authenticated(ctx) An asynchronous context manager that requires an active authenticated session. If no session exists, raises SessionRequiredFault. If the session is not authenticated, raises AUTH_REQUIRED. 2. ensure(ctx) An asynchronous context manager that ensures a session exists. If one is missing from the context, raises SessionRequiredFault. 3. transactional(ctx) A transactional session context that takes a snapshot of the session data dictionary on enter. If any exception is raised inside the context block, it automatically rolls back session modifications to prevent partial/invalid states. from aquilia.sessions import SessionContext # 1. .authenticated() — Context block requiring authentication async def protected_operation(ctx): async with SessionContext.authenticated(ctx) as session: user_id = session.principal.id session["last_action"] = "protected_op" # Committed automatically on exiting the context block successfully # 2. .ensure() — Context block ensuring a session exists async def track_visitor(ctx): async with SessionContext.ensure(ctx) as session: session["visits"] = session.get("visits", 0) + 1 # 3. .transactional() — Context block with automatic snapshot-rollback on exceptions async def critical_update(ctx): async with SessionContext.transactional(ctx) as session: session["balance"] -= 100 # If any exception is raised here, session data is restored to its original snapshot state await process_external_billing() )

### Code Examples
```python
from aquilia.sessions import SessionContext

# 1. .authenticated() — Context block requiring authentication
async def protected_operation(ctx):
    async with SessionContext.authenticated(ctx) as session:
        user_id = session.principal.id
        session["last_action"] = "protected_op"
    # Committed automatically on exiting the context block successfully


# 2. .ensure() — Context block ensuring a session exists
async def track_visitor(ctx):
    async with SessionContext.ensure(ctx) as session:
        session["visits"] = session.get("visits", 0) + 1


# 3. .transactional() — Context block with automatic snapshot-rollback on exceptions
async def critical_update(ctx):
    async with SessionContext.transactional(ctx) as session:
        session["balance"] -= 100
        # If any exception is raised here, session data is restored to its original snapshot state
        await process_external_billing()
```



---

## Session Faults
**URL**: `https://tubox.cloud/docs/sessions/faults`

Sessions / Faults Session Faults All session errors are structured faults belonging to the SECURITY domain. They provide precise status codes, severity indicators, and privacy-safe parameters. SessionFault Hierarchy SessionFault (base class) ├── SessionExpiredFault # Session TTL duration has expired ├── SessionIdleTimeoutFault # Session inactive too long ├── SessionAbsoluteTimeoutFault # Absolute total session lifetime reached ├── SessionInvalidFault # Session ID is malformed or invalid ├── SessionNotFoundFault # Session ID not found in storage ├── SessionPolicyViolationFault # Custom policy/guard check failed ├── SessionConcurrencyViolationFault # Max concurrent sessions exceeded ├── SessionLockedFault # Session is locked in transaction ├── SessionStoreUnavailableFault # Persistent store is unreachable ├── SessionStoreCorruptedFault # Session data is corrupted ├── SessionRotationFailedFault # Session ID rotation failed ├── SessionTransportFault # HTTP transport extraction error ├── SessionForgeryAttemptFault # Malformed/traversing ID token format └── SessionHijackAttemptFault # Fingerprint mismatch (IP/UA mismatch) Fault Registry Reference The session subsystem throws these structured faults. Each has a specific default HTTP code, severity, and retryable flag: , , , , , , , , , , , , , , ].map((item, i) => ( : } HTTP ))} Handling Session Faults Register fault handlers using the @fault_handler decorator. Important: Exception objects do not store a reference to the Session object. Use the request context (ctx.session) to fetch session details inside handlers. from aquilia.faults import fault_handler from aquilia.sessions.faults import ( SessionFault, SessionExpiredFault, SessionHijackAttemptFault, SessionStoreUnavailableFault, ) # Catch generic session faults @fault_handler(SessionFault) async def handle_session_fault(ctx, fault): return ctx.json( , status=fault.http_status) # Catch specific fault (graceful redirect) @fault_handler(SessionExpiredFault) async def handle_expired(ctx, fault): return ctx.redirect("/login?reason=expired") # Catch security hijacking fault (terminate user sessions) @fault_handler(SessionHijackAttemptFault) async def handle_hijack(ctx, fault): # Retrieve active session from RequestCtx (fault has no .session property) session = ctx.session if session and session.principal: # Delete user sessions to mitigate attack active_sessions = await ctx.store.list_by_principal(session.principal.id) for s in active_sessions: await ctx.store.delete(s.id) return ctx.json( , status=403) Fault Properties Session faults expose standardized diagnostic attributes. Session IDs are automatically hashed to prevent leaking secret keys in server logging trails: from aquilia.sessions.faults import SessionExpiredFault fault = SessionExpiredFault(session_id="sess_ABC123...") # Inherited from Fault: print(fault.message) # "Session has expired" print(fault.domain) # FaultDomain.SECURITY print(fault.severity) # Severity.WARN print(fault.public) # True (safe to return to browser) print(fault.retryable) # False print(fault.http_status) # 401 # Session-specific properties: print(fault.session_id_hash) # Hashed ID: "sha256:f124c..." (for safe logging) )

### Code Examples
```python
SessionFault (base class)
├── SessionExpiredFault          # Session TTL duration has expired
├── SessionIdleTimeoutFault      # Session inactive too long
├── SessionAbsoluteTimeoutFault  # Absolute total session lifetime reached
├── SessionInvalidFault          # Session ID is malformed or invalid
├── SessionNotFoundFault         # Session ID not found in storage
├── SessionPolicyViolationFault  # Custom policy/guard check failed
├── SessionConcurrencyViolationFault  # Max concurrent sessions exceeded
├── SessionLockedFault           # Session is locked in transaction
├── SessionStoreUnavailableFault # Persistent store is unreachable
├── SessionStoreCorruptedFault   # Session data is corrupted
├── SessionRotationFailedFault   # Session ID rotation failed
├── SessionTransportFault        # HTTP transport extraction error
├── SessionForgeryAttemptFault   # Malformed/traversing ID token format
└── SessionHijackAttemptFault    # Fingerprint mismatch (IP/UA mismatch)
```

```python
from aquilia.faults import fault_handler
from aquilia.sessions.faults import (
    SessionFault,
    SessionExpiredFault,
    SessionHijackAttemptFault,
    SessionStoreUnavailableFault,
)

# Catch generic session faults
@fault_handler(SessionFault)
async def handle_session_fault(ctx, fault):
    return ctx.json({
        "error": fault.message,
        "code": fault.code,
        "retryable": fault.retryable,
    }, status=fault.http_status)


# Catch specific fault (graceful redirect)
@fault_handler(SessionExpiredFault)
async def handle_expired(ctx, fault):
    return ctx.redirect("/login?reason=expired")


# Catch security hijacking fault (terminate user sessions)
@fault_handler(SessionHijackAttemptFault)
async def handle_hijack(ctx, fault):
    # Retrieve active session from RequestCtx (fault has no .session property)
    session = ctx.session
    
    if session and session.principal:
        # Delete user sessions to mitigate attack
        active_sessions = await ctx.store.list_by_principal(session.principal.id)
        for s in active_sessions:
            await ctx.store.delete(s.id)
            
    return ctx.json({"error": "Access denied"}, status=403)
```

```python
from aquilia.sessions.faults import SessionExpiredFault

fault = SessionExpiredFault(session_id="sess_ABC123...")

# Inherited from Fault:
print(fault.message)        # "Session has expired"
print(fault.domain)         # FaultDomain.SECURITY
print(fault.severity)       # Severity.WARN
print(fault.public)         # True (safe to return to browser)
print(fault.retryable)      # False
print(fault.http_status)    # 401

# Session-specific properties:
print(fault.session_id_hash) # Hashed ID: "sha256:f124c..." (for safe logging)
```



---

## Middleware System & Flows
**URL**: `https://tubox.cloud/docs/middleware`

interface MiddlewareItem const MIDDLEWARE_DATA: MiddlewareItem[] = [ , , , , , , , , , , , , , ]; const ARCHITECTURE_DETAILS: Record = , manifest: , scanner: , sorting: , compilation: , asgi: , resolver: , ctxpool: , di: , exception: , fault: , scope: , auth: , cache: , controller: , typecheck: , ctxrelease: }; function MiddlewareArchitectureDiagram( : ) ; const details = ARCHITECTURE_DETAILS[selectedNode] || ARCHITECTURE_DETAILS.workspace; // Staggered layout list for Runtime Nodes const runtimeNodes = [ , , , , , , , , , , , ]; return ( System Architecture & Lifecycle Select a phase to explore compiling logic and runtime traversal. 1. Compilation & Sorting 2. Runtime Traversal , , , , ].map((node) => ); })} ) : ( INGRESS GATEWAYS TRAVERSAL PIPELINE (PRIORITIZED CLOSURES) ROUTE CORE ⚡ HEALTH BYPASS (Zero-Alloc Sync Flow) , ].map((sc) => ( ))} else if (node.rail === 'bottom') return ( ); })} )} Target: ); } function MiddlewarePipelineVisualizer( : ) ; }; const getThemeColor = (type: string) => }; const getThemeColorHex = (type: string) => }; return ( Interactive Pipeline Flow Explore details, import paths, and fluent configuration syntax. Spine Flow Onion Rings IMPORT PATH REGISTRATION API )} ); })} ) : ( @keyframes radar-sweep to } .radar-sweep-line CORE else if (mw.type === 'protocol') else if (mw.type === 'security') else if (mw.type === 'core') const nodesOfSameType = MIDDLEWARE_DATA.filter(m => m.type === mw.type); const idx = nodesOfSameType.findIndex(m => m.id === mw.id); const count = nodesOfSameType.length; angle = (idx * (360 / count)) + (mw.type === 'protocol' ? 30 : 0); const = getCoordinates(radius, angle); const isSelected = mw.id === selectedId; const colorHex = getThemeColorHex(mw.type); return ( P ); })} PRIORITY: P DOTTED PATH REGISTRATION )} ); } MIDDLEWARE / OVERVIEW Middleware System & Flows Middleware in Aquilia acts as a series of composable wrappers around the request/response lifecycle. Managed by the MiddlewareStack , every middleware conforms to a strict async signature, enabling deterministic priority execution and scoped filtering. Middleware Pipeline Flow MiddlewareStack .build_handler() sorts every registered descriptor by (scope_rank, priority) ascending, then wraps the final handler in reverse order — so the lowest priority number becomes the outermost layer and runs first on the way in / last on the way out. AquiliaServer._setup_middleware() always registers two internal plumbing middlewares first, regardless of any workspace/module configuration — they are framework infrastructure, not part of the user-facing chain: Note the overlap: if you leave .middleware(...) unset, the server falls back to a hardcoded chain of just ExceptionMiddleware (priority 1) + RequestIdMiddleware (priority 10) — ExceptionMiddleware then sits outside the always-on FaultMiddleware (priority 2) as a last-resort catch-all in case FaultEngine.process() re-raises. See Built-in Middleware for the full, source-verified priority table. Scope Controls Order, Not Which Requests Run It scope ("global" / "app" / "controller" / "route") only feeds MiddlewareStack._sort_middlewares()'s scope_order ranking (global=0, app=1, controller=2, route=3) — it decides where in the wrapping order a middleware sits. build_handler() then wraps every registered descriptor unconditionally; nothing in the stack filters a middleware out for requests outside its declared app or route. MiddlewareConfig.scope_target (intended for "app:name" / "route:/pattern" pinning) is accepted as a field but is never read by MiddlewareStack, MiddlewareConfig.to_dict(), or AquiliaServer._register_app_middleware() — it has no runtime effect. A middleware registered with scope="app" from one module's manifest still runs for every request handled by the process, not just that module's routes. If you need a middleware to run only for a subset of routes, gate it inside __call__ yourself (check request.path / request.state) — don't rely on scope for isolation. ⚠ Auto-Discovery Can Silently Reset Your Manifest Config When AppManifest.auto_discover is True (the default), RuntimeRegistry.perform_autodiscovery() scans your module's package for any class named *Middleware or subclassing Middleware . For every discovered class whose import path lives inside your own module package, it rebuilds a fresh MiddlewareConfig(class_path=...) with default scope="global", priority=50, no config — discarding any custom scope, priority, or constructor config you had explicitly set for that same class in middleware=[MiddlewareConfig(...)]. Middleware pointing at classes outside your module's package (e.g. built-ins from aquilia.middleware_ext) are left untouched — only local, in-package middleware classes are re-discovered and reset. from aquilia.manifest import AppManifest, MiddlewareConfig manifest = AppManifest( name="billing", version="0.1.0", middleware=[ # Custom priority/config here is DISCARDED at startup unless # auto_discover=False, because StripeClientMiddleware lives # inside modules.billing (this module's own package). MiddlewareConfig( class_path="modules.billing.middleware:StripeClientMiddleware", priority=30, config= , ), ], auto_discover=False, # The Middleware Contract Every middleware in Aquilia must inherit from the Middleware base class and implement a callable coroutine signature that accepts exactly three parameters. The signature validation is enforced strictly at startup by the MiddlewareStack : , status=401) return await next_handler(request, ctx) Composing a Production Chain MiddlewareChain ships three presets — .chain() (empty), .minimal(), .defaults() (both identical: ExceptionMiddleware priority 1 + RequestIdMiddleware priority 10), and .production() which additionally adds CompressionMiddleware (priority 15) and TimeoutMiddleware (priority 18, 30s). Start from a preset and append your own entries — the list append order doesn't matter, only priority does: from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = ( Workspace("myapp") .middleware( MiddlewareChain .production() # ExceptionMiddleware(1) + RequestIdMiddleware(10) # + CompressionMiddleware(15) + TimeoutMiddleware(18) .use("modules.auth.middleware:JwtAuthMiddleware", priority=25) .use("aquilia.middleware_ext.RateLimitMiddleware", priority=30, default_limit=200, default_window=60.0) ) ) Remember: FaultMiddleware (priority 2, always on) still wraps everything at priority 1 ExceptionMiddleware in this example, so it fires first when a plain Fault subclass is raised. ExceptionMiddleware is your last-resort net if FaultEngine.process() itself re-raises. Workspace-Level Middleware Config Workspace-level middleware configurations define the global pipeline wrapping all application modules. There are two primary styles to declare these in workspace.py: 1. Fluent MiddlewareChain (Recommended Style) Instantiates the fluent MiddlewareChain directly on the Workspace. This provides auto-completion, priority order sorting, and inline argument checks: from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = ( Workspace("myapp") .middleware( MiddlewareChain() .use("aquilia.middleware.ExceptionMiddleware", priority=1) .use("aquilia.middleware.RequestIdMiddleware", priority=5) .use("modules.auth.middleware:JwtAuthMiddleware", priority=25) ) ) ⚠️ Integration.middleware_chain() + .integrate() — Does Nothing at Runtime Integration.middleware_chain() is a static builder that returns a plain dict tagged _integration_type: "middleware_chain". Passed into Workspace.integrate(), it is stored at self._integrations["middleware_chain"], which serializes into config["integrations"]["middleware_chain"] — not the top-level config["middleware_chain"] key. WARNING (verified from source): Every other integration reader (sessions, cache, storage, ...) uses ConfigLoader.get_subsystem_config(), which falls back from get(name) to get(f"integrations. '}"). But ConfigLoader.get_middleware_config() is hand-written as self.get("middleware_chain") only — it has no fallback to integrations.middleware_chain. Entries configured this way are read by nothing and are silently never instantiated into the running MiddlewareStack. Only Workspace.middleware(MiddlewareChain()) (which sets the dedicated top-level _middleware_chain attribute) actually wires middleware. Do not use Integration.middleware_chain() for anything you need to run. from aquilia.workspace import Workspace from aquilia.integrations import Integration workspace = ( Workspace("myapp") .integrate( # This chain is parsed, stored, and then never read again. Integration.middleware_chain( entries=[ , , ] ) ) ) Module-Level Middleware Config Instead of wrapping the entire workspace, modules declare local middlewares inside their own manifest.py via AppManifest. 1. AppManifest middleware Config (Recommended) Passes list of MiddlewareConfig objects specifying the class path, target scope, priority, and custom parameters: from aquilia.manifest import AppManifest, MiddlewareConfig manifest = AppManifest( name="billing", version="0.1.0", middleware=[ MiddlewareConfig( class_path="modules.billing.middleware:StripeClientMiddleware", scope="app", # Affects wrap ORDER only — see warning above, # it does NOT limit this middleware to "billing" priority=30, config= # Custom constructor kwargs ) ], auto_discover=False, # keep this exact priority/config — see warning above ) ⚠️ AppManifest middlewares list (Deprecated) Legacy manifests declared middleware as a list of tuples containing string paths and configuration dicts. WARNING: AppManifest will issue a deprecation warning at startup when detecting the middlewares attribute and will auto-convert them internally to MiddlewareConfig instances. manifest = AppManifest( name="billing", version="0.1.0", # Legacy tuples configuration middlewares=[ ("modules.billing.middleware:StripeClientMiddleware", ) ] ) MiddlewareStack )

### Code Examples
```python
from aquilia.manifest import AppManifest, MiddlewareConfig

manifest = AppManifest(
    name="billing",
    version="0.1.0",
    middleware=[
        # Custom priority/config here is DISCARDED at startup unless
        # auto_discover=False, because StripeClientMiddleware lives
        # inside modules.billing (this module's own package).
        MiddlewareConfig(
            class_path="modules.billing.middleware:StripeClientMiddleware",
            priority=30,
            config={"timeout_seconds": 15.0},
        ),
    ],
    auto_discover=False,  # <-- required to keep the custom priority/config
)
```

```python
from aquilia.middleware import Middleware
from aquilia.response import Response

class CustomMiddleware(Middleware):
    async def __call__(self, request, ctx, next_handler) -> Response:
        # 1. Pre-processing: inspect or modify request
        # request.state["my_key"] = "value"

        # 2. Yield control to the next handler
        response = await next_handler(request, ctx)

        # 3. Post-processing: modify response
        # response.headers["X-Custom"] = "done"
        return response
```

```python
from aquilia.middleware import Middleware
from aquilia.response import Response

class RequireApiKeyMiddleware(Middleware):
    async def __call__(self, request, ctx, next_handler) -> Response:
        api_key = request.header("x-api-key")
        if not api_key or api_key not in ("secret-key-1", "secret-key-2"):
            # Short-circuit: never calls next_handler, so the controller
            # and every middleware with a HIGHER priority number never runs.
            return Response.json({"error": "Invalid API key"}, status=401)

        return await next_handler(request, ctx)
```



---

## Middleware Stack
**URL**: `https://tubox.cloud/docs/middleware/stack`

MIDDLEWARE / STACK & COMPOSITION Middleware Stack The MiddlewareStack manages middleware registration, verifies structural contracts at startup, and compiles the execution pipelines. Startup Contract Validation When you register middleware using .middleware() or direct stack.add(), Aquilia performs four rigorous inspection checks using Python's reflection APIs before running the server: 1. Inheritance Check Class instances must inherit from the Middleware base class. Raw functions bypass this check if they are directly callable. 2. Callability Check The registered object must be callable (i.e. possess an active __call__ method or be a routine). 3. Parameter Count Check Signature inspection (via inspect.signature) enforces exactly three parameters: (request, ctx, next_handler). Binds are verified at registration. 4. Async Coroutine Check The entrypoint MUST be a coroutine function (async def). Sync callables trigger a runtime TypeError at boot. Performance Optimizations: Fast Path For latency-critical routes, building the full middleware chain adds microsecond overhead. Aquilia resolves this via two methods: build_handler(final_handler) Compiles the complete chain. Outermost middleware runs first, tracing frames if enabled. build_fast_handler(final_handler) Compiles a minimal chain. Dynamically strips non-essential, purely informational middlewares (specifically LoggingMiddleware and TimeoutMiddleware) while preserving security boundaries like CORSMiddleware and ExceptionMiddleware . Manipulating the Stack from aquilia.middleware import MiddlewareStack from my_middlewares import SecurityMiddleware, LoggingMiddleware, Handler stack = MiddlewareStack() # 1. Register with scopes and priority stack.add(SecurityMiddleware(), scope="global", priority=10, name="security") stack.add(LoggingMiddleware(), scope="global", priority=90, name="logging") # 2. Build normal handler (executes: Security -> Logging -> Handler) handler = stack.build_handler(final_handler=Handler) # 3. Build fast handler (executes: Security -> Handler; skips Logging) fast_handler = stack.build_fast_handler(final_handler=Handler) Priority Reference (from AquiliaServer._setup_middleware) These are the exact priority numbers AquiliaServer assigns when it wires each built-in middleware — not the fictional numbers you'll find in older docs. Lower number = wraps closer to the outside = runs first on the way in. Class Priority Always On? Fast-Path Skippable ))} ExceptionMiddleware 1 (hardcoded fallback, or your own chain) only if no .middleware() chain configured NO RequestIdMiddleware 10 (hardcoded fallback, or your own chain) only if no .middleware() chain configured NO TimeoutMiddleware 18 (MiddlewareChain.production() preset) only if in your chain YES CompressionMiddleware 15 (MiddlewareChain.production() preset) only if in your chain NO LoggingMiddleware your choice — not auto-registered no — must add explicitly YES Source: aquilia/server.py AquiliaServer._setup_middleware(), plus the individual self.middleware_stack.add(...) calls scattered through session/auth, templates, i18n, cache, and versioning setup. Only build_fast_handler()'s _FAST_SKIP_NAMES frozenset ( "LoggingMiddleware", "TimeoutMiddleware" '}) is skippable on the fast path — every other middleware always runs, whether the request needs it or not. Overview Built-in Middleware )

### Code Examples
```python
from aquilia.middleware import MiddlewareStack
from my_middlewares import SecurityMiddleware, LoggingMiddleware, Handler

stack = MiddlewareStack()

# 1. Register with scopes and priority
stack.add(SecurityMiddleware(), scope="global", priority=10, name="security")
stack.add(LoggingMiddleware(), scope="global", priority=90, name="logging")

# 2. Build normal handler (executes: Security -> Logging -> Handler)
handler = stack.build_handler(final_handler=Handler)

# 3. Build fast handler (executes: Security -> Handler; skips Logging)
fast_handler = stack.build_fast_handler(final_handler=Handler)
```



---

## Built-in Middleware
**URL**: `https://tubox.cloud/docs/middleware/built-in`

MIDDLEWARE / BUILT-IN Built-in Middleware Aquilia packages four highly optimized built-in middlewares covering request identification, error content negotiation, timeouts, and asynchronous compression. RequestIdMiddleware Assigns a unique request ID. To maximize performance, it scans raw ASGI scope headers directly as raw byte arrays, avoiding costly high-level header parsing. Rather than calling slower uuid.uuid4(), it uses os.urandom(16).hex(), executing roughly 4× faster. The ID is stored in both request.state["request_id"] and ctx.request_id, and returned in the response header. from aquilia.middleware import RequestIdMiddleware # Configure on server server.middleware(RequestIdMiddleware(header_name="X-Request-ID")) # Handler usage async def my_handler(request, ctx): request_id = ctx.request_id # accessible directly # or request.state["request_id"] ExceptionMiddleware Intercepts uncaught exceptions and converts them into structured error responses. It uses content negotiation via the client's Accept header: HTML Clients (Accept: text/html) Renders a beautiful debug page in local development (debug=True) detailing local variables, stack frames, and active code slices. Renders a clean production error page when disabled. API Clients (JSON) Enforces security policy ARCH-04: Never leaks stack tracebacks or raw exception strings in JSON bodies. Instead, serialized output follows a strict standard format: ] } } Domain to HTTP Status Code Mapping: SECURITY / auth → 401 / 403 ROUTING / MODEL (Not Found) → 404 VALIDATION (BP200) → 400 IO / STORAGE / CACHE → 502 / 503 SYSTEM / FLOW → 500 TimeoutMiddleware Wraps downstream execution inside a strict time constraint. If execution exceeds the limit, it raises a RequestTimeoutFault which bubbles through the exception middleware, returning a structured 504 Gateway Timeout. from aquilia.middleware import TimeoutMiddleware server.middleware(TimeoutMiddleware(timeout_seconds=15.0)) CompressionMiddleware Compresses response payloads. Because CPU-bound Gzip compression can block Python's single-threaded event loop, this middleware offloads the actual compression call to a background thread pool via asyncio.to_thread. - Skips active streaming and chunked responses. - Emits HTTP header Vary: Accept-Encoding to safeguard cache proxies. from aquilia.middleware import CompressionMiddleware server.middleware(CompressionMiddleware(minimum_size=1024)) # Compress responses >= 1KB MiddlewareStack Static Files )

### Code Examples
```python
from aquilia.middleware import RequestIdMiddleware

# Configure on server
server.middleware(RequestIdMiddleware(header_name="X-Request-ID"))

# Handler usage
async def my_handler(request, ctx):
    request_id = ctx.request_id  # accessible directly
    # or request.state["request_id"]
```

```python
{
  "error": {
    "code": "BP200",
    "message": "Validation failed",
    "domain": "validation",
    "details": [
      { "field": "email", "issue": "invalid email pattern" }
    ]
  }
}
```

```python
from aquilia.middleware import TimeoutMiddleware

server.middleware(TimeoutMiddleware(timeout_seconds=15.0))
```



---

## Static Files Middleware
**URL**: `https://tubox.cloud/docs/middleware/static`

MIDDLEWARE / STATIC FILES Static Files Middleware The StaticMiddleware provides production-grade static asset serving directly at the ASGI level. It employs a custom radix trie prefix matcher for ultra-fast lookups, verifies canonical paths to prevent traversal exploits, and offloads file serving with conditional HTTP caching. Radix Trie Routing Unlike naive string-matching algorithms, StaticMiddleware constructs a compressed radix trie mapping URL prefixes to folder destinations. This ensures route matching operates in O(k) time complexity, where k is the length of the requested path. It easily supports multiple mount points: from aquilia.middleware_ext import StaticMiddleware # Configure multiple directories server.middleware( StaticMiddleware( directories= , cache_max_age=31536000, # 1 year immutable=True ) ) Security Hardening To block malicious directory traversal requests (e.g. /static/../../etc/passwd), the middleware performs canonicalization: It resolves target paths using Python's os.path.realpath and compares them against the canonicalized base directory. If a path escapes the base directory, the middleware immediately raises a SecurityFault and blocks execution. Asset Optimization Pre-compressed Assets (.br, .gz) If a client sends an Accept-Encoding header containing brotli or gzip, the middleware checks if a pre-compiled .br or .gz version of the file exists on disk. If found, it serves the compressed file directly, avoiding dynamic CPU overhead. HTTP Range Requests Supports partial content requests (HTTP 206), enabling clients to stream video and audio files or resume interrupted file downloads efficiently. In-memory Cache Equipped with an LRU (Least Recently Used) cache for small, hot static files. Commonly accessed scripts or icons are served directly from RAM without disk I/O. Constructor Options Parameter Type Default Description directories dict[str, str] None Mapping of URL prefix to folders cache_max_age int 86400 Cache-Control max-age in seconds immutable bool False Adds Cache-Control: immutable directive brotli / gzip bool True Enable pre-compressed file checks index_file str | None "index.html" Default file returned for folder paths html5_history bool False Fall back to index_file on 404s (for SPA routing) Built-in Middleware CORS )

### Code Examples
```python
from aquilia.middleware_ext import StaticMiddleware

# Configure multiple directories
server.middleware(
    StaticMiddleware(
        directories={
            "/static": "./assets/static",
            "/media": "./storage/uploads",
        },
        cache_max_age=31536000, # 1 year
        immutable=True
    )
)
```



---

## CORS Middleware
**URL**: `https://tubox.cloud/docs/middleware/cors`

MIDDLEWARE / CORS CORS Middleware The CORSMiddleware provides full RFC 6454 and Fetch Standard compliant Cross-Origin Resource Sharing. It is optimized with cached origin matching, distinct preflight routing, and vary-caching security headers. LRU Cached Origin Matching To avoid evaluating complex regular expressions or glob matches on every incoming request, CORSMiddleware delegates matching to a specialized _OriginMatcher. This matcher holds an LRU (Least Recently Used) cache with a maximum capacity of 512 entries, keeping origin verification down to O(1) for repeat clients. Supports glob wildcards (e.g. "https://*.domain.com") and pre-compiled regex objects for matching complex subdomains. Configuration from aquilia.middleware_ext import CORSMiddleware import re server.middleware( CORSMiddleware( allow_origins=[ "https://app.example.com", "https://*.internal.net", # Glob subdomain wildcard re.compile(r"^https://[a-z0-9-]+\\.prod\\.com$") # Regex object ], allow_methods=["GET", "POST", "PUT", "DELETE"], allow_headers=["Authorization", "Content-Type"], allow_credentials=True, max_age=3600 ) ) Per-Route Bypassing If a specific endpoint requires custom or dynamic cross-origin logic, you can instruct CORSMiddleware to bypass the request by setting request.state["cors_skip"] = True. Options Reference Option Type Default Description allow_origins list[str | Pattern] None Allowed origins. Supports exact matches, globs, or regex. allow_methods list[str] None List of allowed HTTP methods (e.g. GET, POST). allow_headers list[str] None Allowed request headers during preflight. expose_headers list[str] None Headers safe to expose to browser clients. allow_credentials bool False Allows cookies and Authorization headers to pass. max_age int 600 Preflight OPTIONS response cache duration (seconds). Static Files Rate Limiting )

### Code Examples
```python
from aquilia.middleware_ext import CORSMiddleware
import re

server.middleware(
    CORSMiddleware(
        allow_origins=[
            "https://app.example.com",
            "https://*.internal.net",  # Glob subdomain wildcard
            re.compile(r"^https://[a-z0-9-]+\\.prod\\.com$")  # Regex object
        ],
        allow_methods=["GET", "POST", "PUT", "DELETE"],
        allow_headers=["Authorization", "Content-Type"],
        allow_credentials=True,
        max_age=3600
    )
)
```



---

## Rate Limiting Middleware
**URL**: `https://tubox.cloud/docs/middleware/rate-limit`

MIDDLEWARE / RATE LIMITING Rate Limiting Middleware The RateLimitMiddleware provides token bucket and sliding window rate limiting to protect services against denial-of-service and brute-force traffic. Supported Algorithms Sliding Window (Default) Maintains high accuracy by inspecting the current and previous fixed-time windows. It computes a weighted request count based on overlap, eliminating spikes at window boundaries while using minimal O(1) space. Token Bucket Implements lazy refills on request arrival. Tolerates short-term burst traffic up to a configured capacity, enforcing smooth limits over time. Configuration from aquilia.middleware_ext import ( RateLimitMiddleware, RateLimitRule, ip_key_extractor, api_key_extractor, user_key_extractor, ) limiter = RateLimitMiddleware( rules=[ # 1. Global IP Limit: 100 requests per minute RateLimitRule( limit=100, window=60.0, key_func=ip_key_extractor, ), # 2. Scoped API Key Limit: 1000 requests per hour on /api paths RateLimitRule( limit=1000, window=3600.0, key_func=api_key_extractor, scope="/api", ), # 3. Burst Tolerant Token Bucket for logins (POST only) RateLimitRule( limit=5, window=300.0, algorithm="token_bucket", burst=10, key_func=ip_key_extractor, scope="/auth/login", methods=["POST"], ), ], response_format="json", ) server.middleware(limiter) Key Extractors The rate limiter groups requests by a unique string key. Aquilia ships with three built-in extractors: ip_key_extractor(request) Extracts the client IP address. Respects reverse proxies if ProxyFixMiddleware is active. api_key_extractor(request) Extracts from the X-API-Key header or the Bearer token in the Authorization header. user_key_extractor(request) Extracts the authenticated user ID from request state or identity objects set by Auth middleware. RateLimitRule Options Option Type Default Description limit int 100 Max requests allowed within the window. window float 60.0 Duration of the rate limit window in seconds. algorithm str "sliding_window" Limit algorithm ("sliding_window" or "token_bucket"). key_func Callable ip_key_extractor Function mapping Request to a string rate limit key. burst int | None None Extra burst capacity (token_bucket only). scope str "*" Path prefix this rule applies to. methods list[str] [] HTTP methods restricted by this rule (empty = all). CORS Security Headers )

### Code Examples
```python
from aquilia.middleware_ext import (
    RateLimitMiddleware,
    RateLimitRule,
    ip_key_extractor,
    api_key_extractor,
    user_key_extractor,
)

limiter = RateLimitMiddleware(
    rules=[
        # 1. Global IP Limit: 100 requests per minute
        RateLimitRule(
            limit=100,
            window=60.0,
            key_func=ip_key_extractor,
        ),
        # 2. Scoped API Key Limit: 1000 requests per hour on /api paths
        RateLimitRule(
            limit=1000,
            window=3600.0,
            key_func=api_key_extractor,
            scope="/api",
        ),
        # 3. Burst Tolerant Token Bucket for logins (POST only)
        RateLimitRule(
            limit=5,
            window=300.0,
            algorithm="token_bucket",
            burst=10,
            key_func=ip_key_extractor,
            scope="/auth/login",
            methods=["POST"],
        ),
    ],
    response_format="json",
)

server.middleware(limiter)
```



---

## Security Middleware Suite
**URL**: `https://tubox.cloud/docs/middleware/security`

MIDDLEWARE / SECURITY Security Middleware Suite Aquilia incorporates a production-grade suite of security middlewares covering Content-Security-Policy (CSP), Cross-Site Request Forgery (CSRF), HTTP Strict Transport Security (HSTS), and Helmet-style security headers. CSPMiddleware & CSPPolicy Content-Security-Policy is built using a fluent builder class, CSPPolicy, which is then registered via CSPMiddleware. It generates secure cryptographically random nonces (secrets.token_urlsafe(16)) per-request and injects them to request.state["csp_nonce"]. from aquilia.middleware_ext import CSPMiddleware, CSPPolicy # 1. Build the policy fluently policy = ( CSPPolicy() .default_src("'self'") .script_src("'self'", "'nonce- '", "https://cdn.jsdelivr.net") .style_src("'self'", "'unsafe-inline'") .img_src("'self'", "data:", "https:") ) # 2. Wire into middleware server.middleware(CSPMiddleware(policy=policy, report_only=False)) CSRFMiddleware Defends against Cross-Site Request Forgery. It implements the primary Synchronizer Token Pattern using server-side sessions, falling back to a signed Double Submit Cookie fallback when sessions are disabled. It enforces constant-time string comparisons (secrets.compare_digest) to block timing attack vectors. from aquilia.middleware_ext import CSRFMiddleware server.middleware( CSRFMiddleware( secret_key="my-secure-hmac-key", # Required for cookie fallback integrity cookie_name="_csrf_cookie", header_name="X-CSRF-Token", cookie_secure=True, cookie_httponly=False, # Set False to let JS read it for AJAX exempt_paths=["/api/v1/webhooks"] # Exempt endpoints like Stripe webhook paths ) ) SecurityHeadersMiddleware & HSTS A Helmet-style catch-all security header middleware. It applies standard production defaults to outgoing responses: - X-Content-Type-Options: nosniff (prevents MIME sniffing) - X-Frame-Options: DENY (defends against Clickjacking) - X-XSS-Protection: 1; mode=block (legacy XSS filtering) - Strict-Transport-Security: max-age=31536000 (forces HTTPS connections) from aquilia.middleware_ext import SecurityHeadersMiddleware server.middleware( SecurityHeadersMiddleware( x_content_type_options="nosniff", x_frame_options="DENY", referrer_policy="strict-origin-when-cross-origin" ) ) Rate Limiting Request Scope )

### Code Examples
```python
from aquilia.middleware_ext import CSPMiddleware, CSPPolicy

# 1. Build the policy fluently
policy = (
    CSPPolicy()
    .default_src("'self'")
    .script_src("'self'", "'nonce-{nonce}'", "https://cdn.jsdelivr.net")
    .style_src("'self'", "'unsafe-inline'")
    .img_src("'self'", "data:", "https:")
)

# 2. Wire into middleware
server.middleware(CSPMiddleware(policy=policy, report_only=False))
```

```python
from aquilia.middleware_ext import CSRFMiddleware

server.middleware(
    CSRFMiddleware(
        secret_key="my-secure-hmac-key", # Required for cookie fallback integrity
        cookie_name="_csrf_cookie",
        header_name="X-CSRF-Token",
        cookie_secure=True,
        cookie_httponly=False,          # Set False to let JS read it for AJAX
        exempt_paths=["/api/v1/webhooks"] # Exempt endpoints like Stripe webhook paths
    )
)
```

```python
from aquilia.middleware_ext import SecurityHeadersMiddleware

server.middleware(
    SecurityHeadersMiddleware(
        x_content_type_options="nosniff",
        x_frame_options="DENY",
        referrer_policy="strict-origin-when-cross-origin"
    )
)
```



---

## Request Scope DI Middleware
**URL**: `https://tubox.cloud/docs/middleware/request-scope`

MIDDLEWARE / REQUEST DI SCOPE Request Scope DI Middleware The RequestScopeMiddleware bridges the dependency injection container and the request handler pipeline. It isolates resources per request by spawning isolated child containers and managing their teardown. Request Scoping Lifecycle For each incoming HTTP request, the middleware intercepts execution and performs these operations: 1. Container Resolution Retrieves the parent, module-level dependency container from the active RuntimeRegistry . 2. Child Scope Spawning Spawns an isolated child container by executing container.create_request_scope(). This keeps request-scoped instances isolated from other requests. 3. Instance Registration Binds the active Request instance directly to the child container using container.register_instance(Request, request, scope="request"), making it inject-ready. 4. Context Injection Stores references in request state and the handler context ctx.container = request_container. 5. Teardown & Disposal Upon response completion (inside a finally block), calls request_container.shutdown() or dispose() to release db connections and cached variables. Wiring Middleware from aquilia.middleware_ext import RequestScopeMiddleware, SimplifiedRequestScopeMiddleware # 1. Custom ASGI application level: # app.add_middleware(RequestScopeMiddleware, runtime=runtime) # 2. Simplified HTTP-level middleware setup: server.middleware(SimplifiedRequestScopeMiddleware(runtime=runtime)) Security Headers Sessions )

### Code Examples
```python
from aquilia.middleware_ext import RequestScopeMiddleware, SimplifiedRequestScopeMiddleware

# 1. Custom ASGI application level:
# app.add_middleware(RequestScopeMiddleware, runtime=runtime)

# 2. Simplified HTTP-level middleware setup:
server.middleware(SimplifiedRequestScopeMiddleware(runtime=runtime))
```



---

## Session Middleware
**URL**: `https://tubox.cloud/docs/middleware/session`

MIDDLEWARE / SESSIONS Session Middleware The SessionMiddleware orchestrates session state lifecycle binding per request. It handles token detection, DI container registration, user privilege rotation, and persistence sync. Session Lifecycle Stages During request processing, the session middleware executes the following stages: 1. Session Resolution Extracts the session identifier using the transport backend, loads the session state from store (e.g. Memory, Redis), and validates integrity. 2. State Binding Stores the session in request.state["session"] and ctx.session, and registers the class Session inside the request-scoped DI container. 3. Concurrency Checks If the session is authenticated, verifies active session counts against policy limits (evicting older sessions or blocking the login). 4. Privilege Change & Rotation Tracks changes in authentication states during controller execution. If a login or logout occurs, the middleware triggers session identifier rotation to defend against session fixation attacks. 5. Commit & Sync Saves updated variables to the session store and appends updated transport cookies/headers to the outgoing response. Wiring Session Middleware from aquilia.sessions import SessionEngine, MemoryStore, CookieTransport, SessionPolicy from aquilia.middleware_ext import SessionMiddleware, create_session_middleware engine = SessionEngine( policy=SessionPolicy(max_age=3600), store=MemoryStore(), transport=CookieTransport() ) # Option A: Direct registration server.middleware(SessionMiddleware(session_engine=engine)) # Option B: Optional session middleware (gracefully handles missing engine) server.middleware(create_session_middleware(session_engine=engine, optional=True)) Request Scope )

### Code Examples
```python
from aquilia.sessions import SessionEngine, MemoryStore, CookieTransport, SessionPolicy
from aquilia.middleware_ext import SessionMiddleware, create_session_middleware

engine = SessionEngine(
    policy=SessionPolicy(max_age=3600),
    store=MemoryStore(),
    transport=CookieTransport()
)

# Option A: Direct registration
server.middleware(SessionMiddleware(session_engine=engine))

# Option B: Optional session middleware (gracefully handles missing engine)
server.middleware(create_session_middleware(session_engine=engine, optional=True))
```



---

## LoggingMiddleware
**URL**: `https://tubox.cloud/docs/middleware/logging`

MIDDLEWARE / ACCESS LOGGING LoggingMiddleware The LoggingMiddleware handles high-performance HTTP access logging. It supports multiple layout formatters, timing tracking with microsecond precision, and slow request alerting. Constructor Configuration The middleware constructor accepts several parameters to customize how access logs are gathered: logger_name: str = "aquilia.access" — The logger instance name used to dispatch output. format: str = "dev" — The log line template. Select from "dev" (color-coded terminal), "combined" (standard Nginx/Apache Combined Log Format), or "structured" (JSON output for observability aggregators). slow_threshold_ms: float = 1000.0 — Warns (at Warning log level) if a request duration exceeds this value. skip_paths: set[str] | None = None — Paths excluded from logging (defaults to "}). log_request_body: bool = False — Captures and logs request body byte length. include_headers: list[str] | None = None — List of HTTP request headers to extract and append to the log line extras. Usage Example from aquilia.middleware_ext import LoggingMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = ( Workspace("myapp") .middleware( MiddlewareChain() .use( "aquilia.middleware_ext.logging:LoggingMiddleware", priority=20, format="structured", # JSON outputs slow_threshold_ms=500.0, # Alert on delays > 500ms include_headers=["User-Agent", "Referer"] ) ) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import LoggingMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = (
    Workspace("myapp")
    .middleware(
        MiddlewareChain()
        .use(
            "aquilia.middleware_ext.logging:LoggingMiddleware",
            priority=20,
            format="structured",          # JSON outputs
            slow_threshold_ms=500.0,       # Alert on delays > 500ms
            include_headers=["User-Agent", "Referer"]
        )
    )
)
```



---

## CSPMiddleware
**URL**: `https://tubox.cloud/docs/middleware/csp`

MIDDLEWARE / CONTENT SECURITY POLICY CSPMiddleware The CSPMiddleware restricts resource loading, defending applications against Cross-Site Scripting (XSS) and data injection attacks. Fluent CSPPolicy Builder Rather than building manual policy strings, Aquilia provides the fluent CSPPolicy class to configure resource loading policies: .default_src(*sources) — Default fallback sources for most resource types. .script_src(*sources) — Specifies valid sources for JavaScript scripts. .style_src(*sources) — Specifies valid sources for style sheets. .img_src(*sources) — Specifies valid sources for images. .font_src(*sources) — Specifies valid sources for fonts. Request Nonce Generation When nonce=True is configured, the middleware automatically generates a cryptographically secure, per-request nonce (via secrets.token_urlsafe(16)). The nonce is injected into the policy string wherever 'nonce- "}' is declared, and is made accessible in templates via the request context: console.log("Safe script execution"); Usage Example from aquilia.middleware_ext import CSPMiddleware, CSPPolicy from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain # Build policy fluently policy = ( CSPPolicy() .default_src("'self'") .script_src("'self'", "'nonce- '") .style_src("'self'", "'unsafe-inline'") ) workspace = Workspace("myapp").middleware( MiddlewareChain().use( "aquilia.middleware_ext.security:CSPMiddleware", priority=12, policy=policy, nonce=True ) ) Overview )

### Code Examples
```python
<!-- Inject nonce dynamically in templates -->
<script nonce="{{ request.state.csp_nonce }}">
    console.log("Safe script execution");
</script>
```

```python
from aquilia.middleware_ext import CSPMiddleware, CSPPolicy
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

# Build policy fluently
policy = (
    CSPPolicy()
    .default_src("'self'")
    .script_src("'self'", "'nonce-{nonce}'")
    .style_src("'self'", "'unsafe-inline'")
)

workspace = Workspace("myapp").middleware(
    MiddlewareChain().use(
        "aquilia.middleware_ext.security:CSPMiddleware",
        priority=12,
        policy=policy,
        nonce=True
    )
)
```



---

## CSRFMiddleware
**URL**: `https://tubox.cloud/docs/middleware/csrf`

MIDDLEWARE / CSRF PROTECTION CSRFMiddleware The CSRFMiddleware blocks Cross-Site Request Forgery attacks. It uses the Synchronizer Token Pattern backed by server-side sessions, falling back to a signed Double Submit Cookie when sessions are unavailable. Constructor Configuration The middleware is highly configurable to suit standard SPA or MVC page rendering layouts: secret_key: str | None = None — HMAC key for double-submit cookie validation. Generates an ephemeral key per-process if omitted. header_name: str = "X-CSRF-Token" — The request header name containing the validation token. field_name: str = "_csrf_token" — The form field name containing the validation token. exempt_paths: list[str] | None = None — List of URL prefixes exempted from CSRF validation (e.g. webhooks). exempt_content_types: list[str] | None = None — Exempts requests carrying matching content types (e.g. "application/json"). trust_ajax: bool = False — Bypasses validation if X-Requested-With: XMLHttpRequest is present, trusting the browser's same-origin boundary. Usage Example from aquilia.middleware_ext import CSRFMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = Workspace("myapp").middleware( MiddlewareChain().use( "aquilia.middleware_ext.security:CSRFMiddleware", priority=15, secret_key="production-only-secure-key-phrase", exempt_paths=["/stripe/webhooks"], trust_ajax=True ) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import CSRFMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = Workspace("myapp").middleware(
    MiddlewareChain().use(
        "aquilia.middleware_ext.security:CSRFMiddleware",
        priority=15,
        secret_key="production-only-secure-key-phrase",
        exempt_paths=["/stripe/webhooks"],
        trust_ajax=True
    )
)
```



---

## HSTSMiddleware
**URL**: `https://tubox.cloud/docs/middleware/hsts`

MIDDLEWARE / HSTS SECURITY HSTSMiddleware The HSTSMiddleware enforces HTTPS-only communication by appending the HTTP Strict Transport Security header to responses. Constructor Configuration The middleware constructor defines HSTS parameters standard across modern web security audits: max_age: int = 31536000 — The number of seconds browsers should remember this domain must only be accessed via HTTPS (defaults to 1 year). include_subdomains: bool = True — Applies the strict HTTPS directive recursively to all subdomains. preload: bool = False — Opts the domain into major browser HSTS preload list registries (e.g. hstspreload.org). Usage Example from aquilia.middleware_ext import HSTSMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = Workspace("myapp").middleware( MiddlewareChain().use( "aquilia.middleware_ext.security:HSTSMiddleware", priority=10, max_age=63072000, # 2 years include_subdomains=True, preload=True ) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import HSTSMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = Workspace("myapp").middleware(
    MiddlewareChain().use(
        "aquilia.middleware_ext.security:HSTSMiddleware",
        priority=10,
        max_age=63072000,             # 2 years
        include_subdomains=True,
        preload=True
    )
)
```



---

## HTTPSRedirectMiddleware
**URL**: `https://tubox.cloud/docs/middleware/https-redirect`

MIDDLEWARE / HTTPS REDIRECT HTTPSRedirectMiddleware The HTTPSRedirectMiddleware intercepts incoming unsecured HTTP requests and redirects them to their equivalent HTTPS addresses. Constructor Configuration Configure redirect responses and host exemptions to facilitate local development and health check pings: redirect_status: int = 301 — HTTP redirect status code (e.g. 301 Moved Permanently or 307 Temporary Redirect). exclude_paths: list[str] | None = None — Paths excluded from redirections. Use this to allow unsecured health checks (e.g. ["/healthz"]). exclude_hosts: list[str] | None = None — Hostnames exempt from redirections (defaults to ["localhost", "127.0.0.1", "0.0.0.0"]). Usage Example from aquilia.middleware_ext import HTTPSRedirectMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = Workspace("myapp").middleware( MiddlewareChain().use( "aquilia.middleware_ext.security:HTTPSRedirectMiddleware", priority=8, redirect_status=307, exclude_paths=["/ping"] ) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import HTTPSRedirectMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = Workspace("myapp").middleware(
    MiddlewareChain().use(
        "aquilia.middleware_ext.security:HTTPSRedirectMiddleware",
        priority=8,
        redirect_status=307,
        exclude_paths=["/ping"]
    )
)
```



---

## ProxyFixMiddleware
**URL**: `https://tubox.cloud/docs/middleware/proxy-fix`

MIDDLEWARE / PROXY HEADERS CORRECTION ProxyFixMiddleware The ProxyFixMiddleware corrects request schemes, client IPs, and ports when running behind reverse proxies (like Nginx, HAProxy, AWS ALB, or Cloudflare). It uses CIDR networks to restrict header trust to verified proxy IPs. Constructor Configuration Configure header trust boundaries to prevent headers spoofing by malicious clients: trusted_proxies: list[str] | None = None — CIDR subnet masks or exact IP addresses of trusted proxies. (Defaults to localhost subnets, private subnets 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). x_for: int = 1 — Number of proxy hops to trust/unwrap from the right of X-Forwarded-For list. x_proto: int = 1 — Trusted hops for X-Forwarded-Proto scheme header. x_host: int = 1 — Trusted hops for X-Forwarded-Host domain name header. x_port: int = 0 — Trusted hops for X-Forwarded-Port header. (Disabled by default). Usage Example from aquilia.middleware_ext import ProxyFixMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = Workspace("myapp").middleware( MiddlewareChain().use( "aquilia.middleware_ext.security:ProxyFixMiddleware", priority=3, trusted_proxies=["10.0.0.0/16", "192.168.1.1"], x_for=2, # Trust dual proxies hops x_proto=1 ) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import ProxyFixMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = Workspace("myapp").middleware(
    MiddlewareChain().use(
        "aquilia.middleware_ext.security:ProxyFixMiddleware",
        priority=3,
        trusted_proxies=["10.0.0.0/16", "192.168.1.1"],
        x_for=2,                     # Trust dual proxies hops
        x_proto=1
    )
)
```



---

## EffectMiddleware & FlowContextMiddleware
**URL**: `https://tubox.cloud/docs/middleware/effect`

MIDDLEWARE / EFFECTS ACQUISITION EffectMiddleware & FlowContextMiddleware These middlewares integrate the Effects capability-resolution system with the ASGI HTTP pipeline, enabling automatic acquisition and releasing of transactional resources. 1. EffectMiddleware The EffectMiddleware inspects handler route declarations (like @requires()) at request start, calls the active providers to acquire the resources, and cleans them up after the handler finishes executing. effect_registry: EffectRegistry | None = None — The registry carrying registered side-effect providers. auto_detect: bool = True — Enables automatic inspection of __flow_effects__ on route handlers. 2. FlowContextMiddleware The FlowContextMiddleware sets up a thread-safe context object carrying request and capability states, exposing them to sub-guards or nested call pipelines. Usage Example from aquilia.middleware_ext import EffectMiddleware, FlowContextMiddleware from aquilia.workspace import Workspace from aquilia.integrations import MiddlewareChain workspace = Workspace("myapp").middleware( MiddlewareChain() .use("aquilia.middleware_ext.effect_middleware:FlowContextMiddleware", priority=15) .use("aquilia.middleware_ext.effect_middleware:EffectMiddleware", priority=16) ) Overview )

### Code Examples
```python
from aquilia.middleware_ext import EffectMiddleware, FlowContextMiddleware
from aquilia.workspace import Workspace
from aquilia.integrations import MiddlewareChain

workspace = Workspace("myapp").middleware(
    MiddlewareChain()
    .use("aquilia.middleware_ext.effect_middleware:FlowContextMiddleware", priority=15)
    .use("aquilia.middleware_ext.effect_middleware:EffectMiddleware", priority=16)
)
```



---

## Aquilary Registry
**URL**: `https://tubox.cloud/docs/aquilary`

ADVANCED / AQUILARY REGISTRY Aquilary Registry The Aquilary is Aquilia's manifest-driven module registry. It manages module declaration, resolves dependencies topologically, indexes route structures, and generates secure cryptographic fingerprints to enable deterministic hot-reloads. Two-Phase Registry Lifecycle To prevent import-time side effects and keep development tooling fast, Aquilia separates registry instantiation into two distinct phases: APPMANIFESTS Declarative inputs MANIFESTLOADER Safe loading (no imports) VALIDATION & GRAPH Cycles & Route conflicts AQUILARYREGISTRY Fingerprinted static state AUTO-DISCOVERY Lazy class load & scan RUNTIMEREGISTRY ASGI server compilation 1. Static Validation Phase Executed by AquilaryRegistry . Reads manifest files without importing controllers or services. It checks route conflicts, resolves dependency cycles, and computes the load order topologically. 2. Lazy Compilation Phase Managed by RuntimeRegistry . Active only when bootstrapping the live ASGI server. Performs runtime package scans, imports user code, compiles route trees, and builds DI containers. Workspace Integration Your workspace structure declares the relationships between modules. Here's a clean workspace instantiation: from aquilia import Workspace, Module from modules.users import UserController, UserService from modules.products import ProductController, ProductService workspace = Workspace( modules=[ Module("users", controllers=[UserController], providers=[UserService]), Module("products", controllers=[ProductController], providers=[ProductService]), Module("orders", controllers=["modules.orders.controllers:OrderController"], providers=["modules.orders.services:OrderService"], imports=["users", "products"], # Declares load dependency ), ], ) CLI Validation Tooling The CLI operates directly on the static metadata phase, inspecting the registry without importing user classes: # 1. Validate manifest structure and dependency safety aq validate # 2. Inspect route structures aq inspect routes # 3. View module dependencies aq inspect modules Middleware Manifest System )

### Code Examples
```python
from aquilia import Workspace, Module
from modules.users import UserController, UserService
from modules.products import ProductController, ProductService

workspace = Workspace(
    modules=[
        Module("users", controllers=[UserController], providers=[UserService]),
        Module("products", controllers=[ProductController], providers=[ProductService]),
        Module("orders",
            controllers=["modules.orders.controllers:OrderController"],
            providers=["modules.orders.services:OrderService"],
            imports=["users", "products"], # Declares load dependency
        ),
    ],
)
```

```python
# 1. Validate manifest structure and dependency safety
aq validate

# 2. Inspect route structures
aq inspect routes

# 3. View module dependencies
aq inspect modules
```



---

## Manifest Loading & Validation
**URL**: `https://tubox.cloud/docs/aquilary/manifest`

AQUILARY / MANIFEST SYSTEM Manifest Loading & Validation The manifest system provides safe, import-free module discovery. By loading declarations lazily, Aquilia compiles dependency layouts without executing user module imports. ManifestLoader The ManifestLoader class parses manifest specifications from multiple sources. It accepts a list of sources—which can be direct Python manifest classes, absolute/relative paths to Python manifest files, or DSL (YAML/JSON) files: from aquilia.aquilary import ManifestLoader loader = ManifestLoader() # Load multiple modules from mixed sources (safe, no import side effects) manifests = loader.load_manifests( sources=[ "modules/auth/manifest.py", "modules/users/manifest.yaml", # DSL config support ], allow_fs_autodiscovery=True # Scan standard directories ) for m in manifests: print(f"Loaded: v [Origin: ]") Registry Validation Once loaded, the RegistryValidator inspects the manifest declarations. It compiles a validation report covering schema compatibility, route collisions, and duplicate app declarations: from aquilia.aquilary import RegistryValidator, RegistryMode validator = RegistryValidator(mode=RegistryMode.PROD) # Run validations on manifests report = validator.validate_manifests( manifests, config, workspace_modules=workspace_modules_config ) if report.has_errors(): raise Exception(report.to_exception()) Core Validation Rules Validation Code Focus Description DuplicateAppError Uniqueness Triggers if two modules declare the exact same name. RouteConflictError Routing Flags overlapping paths or colliding HTTP endpoint route templates. DependencyCycleError Topology Raised when circular dependencies exist between module imports. Overview Runtime Registry )

### Code Examples
```python
from aquilia.aquilary import ManifestLoader

loader = ManifestLoader()

# Load multiple modules from mixed sources (safe, no import side effects)
manifests = loader.load_manifests(
    sources=[
        "modules/auth/manifest.py",
        "modules/users/manifest.yaml", # DSL config support
    ],
    allow_fs_autodiscovery=True # Scan standard directories
)

for m in manifests:
    print(f"Loaded: {m.name} v{m.version} [Origin: {m.__source__}]")
```

```python
from aquilia.aquilary import RegistryValidator, RegistryMode

validator = RegistryValidator(mode=RegistryMode.PROD)

# Run validations on manifests
report = validator.validate_manifests(
    manifests,
    config,
    workspace_modules=workspace_modules_config
)

if report.has_errors():
    raise Exception(report.to_exception())
```



---

## Runtime Registry & Discovery
**URL**: `https://tubox.cloud/docs/aquilary/runtime`

AQUILARY / RUNTIME REGISTRY Runtime Registry & Discovery The RuntimeRegistry class compiles the static module graph metadata into a live application server state, performing package discovery, lazily importing controllers, and building DI containers. Auto-Discovery Phases When calling perform_autodiscovery(), the registry scans modules. "} recursively up to a depth of 5, identifying and importing classes matching predicate rules: 1. Controller Scanning Discovers classes whose names end with "Controller" or that directly inherit from Controller . 2. Service Scanning Discovers dependency injection services whose names end with "Service" or declare the __di_scope__ attribute. 3. Socket Controllers Scans for classes decorated with @Socket or whose names end with "SocketController". 4. Tasks and Models Imports tasks.py to trigger background task registrations, and scans database models to catalog schemas. Bootstrapping from aquilia.aquilary import RuntimeRegistry # 1. Instantiate runtime registry from compiled metadata runtime = RuntimeRegistry.from_metadata(registry_meta, config) # 2. Perform autodiscovery package scan (depth=5) runtime.perform_autodiscovery() # 3. Import controllers and build the ASGI route tables runtime.compile_routes() Manifest System Fingerprinting )

### Code Examples
```python
from aquilia.aquilary import RuntimeRegistry

# 1. Instantiate runtime registry from compiled metadata
runtime = RuntimeRegistry.from_metadata(registry_meta, config)

# 2. Perform autodiscovery package scan (depth=5)
runtime.perform_autodiscovery()

# 3. Import controllers and build the ASGI route tables
runtime.compile_routes()
```



---

## Registry Fingerprinting
**URL**: `https://tubox.cloud/docs/aquilary/fingerprint`

AQUILARY / FINGERPRINTING Registry Fingerprinting Aquilia uses content-addressable fingerprinting to verify application configuration state, detect hot-reload requirements, and guarantee reproducible production deployments. Deterministic SHA-256 Generation The FingerprintGenerator compiles a canonical dictionary representation of the application state, serializes it to sorted JSON, and computes a SHA-256 hash. To ensure reproducibility across local machines, Docker images, and cloud providers, it filters out environment variations: Included in Hash App manifest names and versions Dependency relationships between modules Route paths, parameters, and HTTP methods Config keys and schemas (structure only) Excluded from Hash Environment variable values Absolute path structures Build or compilation timestamps Active runtime container references Verifying Fingerprints from aquilia.aquilary import FingerprintGenerator # Compute the fingerprint of the live registry generator = FingerprintGenerator() fingerprint = generator.generate(app_contexts, config, mode) print(f"Active Fingerprint: ") # -> "8f9e1a2b3c4d5e6f..." # If deployment fingerprint differs from frozen disk configuration: # 1. Hot reload module registry # 2. Re-compile route endpoints Runtime Registry Subsystem Overview )

### Code Examples
```python
from aquilia.aquilary import FingerprintGenerator

# Compute the fingerprint of the live registry
generator = FingerprintGenerator()
fingerprint = generator.generate(app_contexts, config, mode)

print(f"Active Fingerprint: {fingerprint}")
# -> "8f9e1a2b3c4d5e6f..."

# If deployment fingerprint differs from frozen disk configuration:
# 1. Hot reload module registry
# 2. Re-compile route endpoints
```



---

## Subsystem Overview
**URL**: `https://tubox.cloud/docs/subsystem`

SUBSYSTEM / OVERVIEW Subsystem Overview The Subsystem is a unified, strongly-typed architecture combining composable execution flows and declarative capability effects. It compiles request-handling steps into pipelines while lazily resolving infrastructure requirements (like databases or caches) on-demand through an extensible registry. Philosophy & Decoupling In traditional backend frameworks, handlers (e.g., controllers or services) instantiate database connections, cache clients, or message brokers directly. This tight coupling creates mock-heavy tests, configuration drift, and makes it challenging to swap backends (like switching from a local filesystem storage to AWS S3). Aquilia solves this via the Explicit Capability Injection pattern. Handlers declare *what* capability they require via a typed token, and the runtime handles the lifecycle (setup, connection pooling, and automatic commit/rollback cleanup) around the request execution. Request Lifecycle & Flow Architecture The diagram below illustrates how an incoming request flows through the compiled Flow pipeline phases, resolving capability requirements lazily through the registry proxy, and releasing resources safely. HTTP REQUEST Client Inbound FLOWCONTEXT Scoped container GUARDS Auth & validation TRANSFORMS Payload molding EFFECT LEASE Lazy acquisition PIPELINE HANDLER Core execution DISPOSAL & HOOKS Commit / Rollback LIFO Workspace Integration To use the capability system, register EffectMiddleware and FlowContextMiddleware in your application's middleware stack inside your project's workspace configuration (usually in workspace.py). IMPORTANT NOTE ON ORDERING: The FlowContextMiddleware must precede EffectMiddleware in execution (meaning it has a lower priority number or is added first in the chain). This ensures that a request-scoped FlowContext exists so that the Effect Middleware can inject the acquired capability handles into it. from aquilia.workspace import Workspace from aquilia.middleware import MiddlewareChain app = ( Workspace.new("aquilia-project") .middleware( MiddlewareChain.chain() .defaults() .use("aquilia.middleware_ext.FlowContextMiddleware", priority=14) .use("aquilia.middleware_ext.EffectMiddleware", priority=15) ) ) The framework will load the middleware string paths and dynamically inject dependencies. The EffectMiddleware will look for a configured EffectRegistry in the global dependency injection container and defer to it. Declaring Capabilities with @requires To declare that a route handler or flow pipeline node requires a capability, decorate it with the @requires decorator, passing in the names of the required effects (e.g. "DBTx", "Cache"). CRITICAL DECORATOR ORDERING: The @requires(...) decorator must be placed **below** the routing decorators (e.g. @POST or @Get). Python evaluates decorators from bottom to top; applying @requires closest to the method body registers its metadata under __flow_effects__ on the original method, allowing routing compiles to read it. from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires class CorporateOrderIngestController(Controller): @POST("/orders/ingest") @requires("DBTx", "Cache") async def ingest_corporate_order(self, ctx: RequestCtx) -> dict: # Resolve capabilities safely db = ctx.get_effect("DBTx") # Returns a DBTxHandle cache = ctx.get_effect("Cache") # Returns a CacheServiceHandle body = await ctx.json() # 1. Store order payload in Database order_id = await db.fetch_val( "INSERT INTO orders (corporate_id, total, status) VALUES (?, ?, ?) RETURNING id", (body["corporate_id"], body["total"], "RECEIVED") ) # 2. Update cache with hot corporate statistics latest_orders = await cache.get(f"corp: :recent") or [] latest_orders.insert(0, ) await cache.set(f"corp: :recent", latest_orders[:5], ttl=600) return Under The Hood: Deferred Resolving Aquilia uses a *lazy deferred registry* model via the internal proxy _DeferredEffectRegistry. This resolves a fundamental bootstrap ordering constraint: 1. Bootstrap: Middleware stack is constructed early before providers are registered. 2. ASGI Startup: Subsystems load and register their effect providers with the central registry. 3. Request Time: The lazy proxy forwards lookups to the populated live registry on every request. When a request comes in, the Flow pipeline resolves capability requirements dynamically, executes guards and transforms, matches scope permissions, and disposes of transactions on request completion. Flow Pipeline Architecture & Compositions The Flow system enables you to chain independent callable logic blocks (guards, transforms, handlers, and hooks) into a single execution path. By leveraging the bitwise OR (|) operator, you can compose pipelines dynamically, merging reusable middleware blocks with handler nodes. Each phase receives a structured FlowContext containing the request, DI scope, and acquired capability effects: from aquilia.flow import pipeline, FlowContext, requires from aquilia.response import Response # 1. Custom Security Guard Node async def check_api_clearance(ctx: FlowContext) -> bool | Response: clearance = ctx.request.headers.get("X-Clearance-Level") if not clearance or int(clearance) FlowContext: body = await ctx.request.json() ctx.state["raw_payload"] = body ctx.state["processed_at"] = time.time() return ctx # 3. Main Request Handler (Requires Database Capability) @requires("DBTx") async def persist_audit_log(ctx: FlowContext) -> dict: db = ctx.get_effect("DBTx") payload = ctx.state["raw_payload"] log_id = await db.fetch_val( "INSERT INTO audit_logs (level, data) VALUES (?, ?) RETURNING id", (ctx.state["clearance_level"], str(payload)) ) return # 4. Compose pipelines using the '|' operator security_pipeline = pipeline("security").guard(check_api_clearance, priority=10) enrich_pipeline = pipeline("enrich").transform(enrich_payload) full_pipeline = security_pipeline | enrich_pipeline | pipeline("action").handler(persist_audit_log) # 5. Execution and outcome inspection result = await full_pipeline.execute(flow_context, effect_registry=registry) if result.is_success: print(f"Executed handler output: ") elif result.is_guarded: print(f"Short-circuited by guard: ") The EffectProvider Contract Every effect resource must have a corresponding EffectProvider implementation. It defines five lifecycle hooks: async def initialize(self) -> None Invoked once at server startup. Ideal for connecting client pools or setting up driver connections. async def acquire(self, mode: str | None = None) -> Any Invoked per-request. Retrieves the scoped handle representing the resource connection (e.g. transaction, bucket client). async def release(self, resource: Any, success: bool = True) -> None Invoked when a request finishes. The success boolean flags whether the endpoint completed without throwing an exception, allowing providers to safely commit or abort changes. async def finalize(self) -> None Invoked at server shutdown. Closes client connections and drains active pools safely. async def health_check(self) -> dict[str, Any] Aggregates connection health metrics (e.g., checks connection ping, error counts). Returns a dictionary with a "healthy" boolean key. Topological Dependency Resolution (Layer) Aquilia integrates an Effect-TS inspired Layer class that facilitates modular initialization. Layers specify setup factories and declare explicit dependencies. The runtime resolves the full dependency graph topologically at startup. For a detailed guide on managing initialization layers, composing them, and acquiring resources outside of HTTP paths, see the dedicated Layers & Compositions reference. from aquilia.flow import Layer from aquilia.effects import DBTxProvider, CacheProvider # Define configuration dependencies config_layer = Layer( name="Config", factory=lambda: AppConfig.load_from_env() ) db_layer = Layer( name="DBTx", factory=lambda cfg: DBTxProvider(cfg.database_url), deps=["Config"] ) cache_layer = Layer( name="Cache", factory=lambda cfg: CacheProvider(cfg.cache_backend), deps=["Config"] ) # Compose and bootstrap layers sequentially app_layer = Layer.merge(db_layer, cache_layer) Fingerprinting Flow Pipelines )

### Code Examples
```python
from aquilia.workspace import Workspace
from aquilia.middleware import MiddlewareChain

app = (
    Workspace.new("aquilia-project")
    .middleware(
        MiddlewareChain.chain()
        .defaults()
        .use("aquilia.middleware_ext.FlowContextMiddleware", priority=14)
        .use("aquilia.middleware_ext.EffectMiddleware", priority=15)
    )
)
```

```python
from aquilia.controller import Controller, POST, RequestCtx
from aquilia.flow import requires

class CorporateOrderIngestController(Controller):
    @POST("/orders/ingest")
    @requires("DBTx", "Cache")
    async def ingest_corporate_order(self, ctx: RequestCtx) -> dict:
        # Resolve capabilities safely
        db = ctx.get_effect("DBTx")        # Returns a DBTxHandle
        cache = ctx.get_effect("Cache")    # Returns a CacheServiceHandle
        
        body = await ctx.json()
        
        # 1. Store order payload in Database
        order_id = await db.fetch_val(
            "INSERT INTO orders (corporate_id, total, status) VALUES (?, ?, ?) RETURNING id",
            (body["corporate_id"], body["total"], "RECEIVED")
        )
        
        # 2. Update cache with hot corporate statistics
        latest_orders = await cache.get(f"corp:{body['corporate_id']}:recent") or []
        latest_orders.insert(0, {"order_id": order_id, "total": body["total"]})
        await cache.set(f"corp:{body['corporate_id']}:recent", latest_orders[:5], ttl=600)
        
        return {"status": "order_ingested", "order_id": order_id}
```

```python
from aquilia.flow import pipeline, FlowContext, requires
from aquilia.response import Response

# 1. Custom Security Guard Node
async def check_api_clearance(ctx: FlowContext) -> bool | Response:
    clearance = ctx.request.headers.get("X-Clearance-Level")
    if not clearance or int(clearance) < 3:
        # Returning a Response immediately short-circuits the pipeline
        return Response.json({"error": "Insufficient Clearance Level"}, status=403)
    ctx.state["clearance_level"] = int(clearance)
    return True

# 2. Reusable State Transformation Node
async def enrich_payload(ctx: FlowContext) -> FlowContext:
    body = await ctx.request.json()
    ctx.state["raw_payload"] = body
    ctx.state["processed_at"] = time.time()
    return ctx

# 3. Main Request Handler (Requires Database Capability)
@requires("DBTx")
async def persist_audit_log(ctx: FlowContext) -> dict:
    db = ctx.get_effect("DBTx")
    payload = ctx.state["raw_payload"]
    
    log_id = await db.fetch_val(
        "INSERT INTO audit_logs (level, data) VALUES (?, ?) RETURNING id",
        (ctx.state["clearance_level"], str(payload))
    )
    return {"log_id": log_id, "status": "persisted"}

# 4. Compose pipelines using the '|' operator
security_pipeline = pipeline("security").guard(check_api_clearance, priority=10)
enrich_pipeline = pipeline("enrich").transform(enrich_payload)

full_pipeline = security_pipeline | enrich_pipeline | pipeline("action").handler(persist_audit_log)

# 5. Execution and outcome inspection
result = await full_pipeline.execute(flow_context, effect_registry=registry)
if result.is_success:
    print(f"Executed handler output: {result.value}")
elif result.is_guarded:
    print(f"Short-circuited by guard: {result.guard.name}")
```



---

## Built-in Capabilities
**URL**: `https://tubox.cloud/docs/subsystem/built-in`

EFFECTS / BUILT-IN Built-in Capabilities Aquilia packages five core capabilities natively, covering database transactions, memory caches, messaging brokers, background task executors, HTTP clients, and unified blob storage. EXPLORE API ) })} Overview )


---

## Database Transaction Effect
**URL**: `https://tubox.cloud/docs/subsystem/dbtx`

EFFECTS / DATABASE TRANSACTION Database Transaction Effect The DBTx effect provides transactional database connections from the application pool. Implemented by the DBTxProvider , it automatically commits on request completion or rolls back when faults occur. How Transactions are Bound When a handler requests database access, pulling raw connections manually can lead to leaked sessions or uncommitted transaction blocks. The DBTx effect treats transactions as request-scoped resources. It wraps request processing with an atomic database scope, enforcing database safety at the framework boundaries. Token Configuration & Modes You can declare your database requirements in two modes using Python's class indexing syntax: DBTx["read"] Acquires a database connection configured as read-only. This optimizes SELECT performance, permits routing queries to read replicas, and raises errors if writing is attempted. DBTx["write"] Acquires a database connection and immediately initiates a transaction block. Commits the transaction when the handler finishes successfully, or issues a SQL ROLLBACK if any exception escapes the handler. The DBTxHandle Interface When acquired, the resource injected into the context is an instance of DBTxHandle . It inherits from dict to keep metadata accessible, but exposes async helper wrappers to execute SQL within the active transaction: await handle.execute(sql: str, params: Sequence | None = None) -> AsyncCursor Executes a SQL statement (e.g. INSERT, UPDATE, DELETE) binding parameters to prevent SQL injection. Returns an active query cursor. await handle.fetch_all(sql: str, params: Sequence | None = None) -> list[dict[str, Any]] Executes a query and returns all result rows mapped as key-value dictionaries. await handle.fetch_one(sql: str, params: Sequence | None = None) -> dict[str, Any] | None Fetches a single row. Returns a dictionary or None if no records match. await handle.fetch_val(sql: str, params: Sequence | None = None) -> Any Convenience method that fetches the first column of the first row (ideal for scalar queries like COUNT or returning primary keys). await handle.execute_many(sql: str, params_list: Sequence[Sequence]) -> None Executes the SQL statement iteratively over a list of parameter tuples in a highly optimized batch database operation. Exposed Properties handle.connection — Returns the underlying raw DB engine connection or pool instance. handle.mode — Returns the transaction acquisition mode: "read" or "write". handle.transaction — Points to the active transaction context instance. handle.acquired_at — The monotonic timestamp when the connection was leased. Practical Code Examples 1. Write Operation with Auto-Rollback (E-Commerce Checkout) If any exception is raised during execution, the transaction is rolled back automatically. The example below shows an enterprise e-commerce checkout handler checking inventory, deducting balances, recording audit ledgers, and allocating reward points: from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from aquilia.effects import DBTx from aquilia.faults.domains import OutOfStockFault, PaymentFailedFault class CheckoutController(Controller): @POST("/checkout") @requires(DBTx["write"]) async def process_checkout(self, ctx: RequestCtx) -> dict: body = await ctx.json() db = ctx.get_effect("DBTx") # DBTxHandle instance # 1. Lock and inspect product stock stock = await db.fetch_val( "SELECT stock FROM products WHERE id = ? FOR UPDATE", (body["product_id"],) ) if stock is None or stock 2. Read-Only Retrieval Optimization (SaaS Tenant Analytics) Using the read-only mode avoids starting transactional locks on the database and signals to the loader that the connection can safely target replica instances: Overview Cache Effect )

### Code Examples
```python
DBTx["read"]
```

```python
DBTx["write"]
```

```python
await handle.execute(sql: str, params: Sequence | None = None) -> AsyncCursor
```



---

## Cache Effect
**URL**: `https://tubox.cloud/docs/subsystem/cache`

EFFECTS / CACHE EFFECT Cache Effect The CacheEffect enables scoped key-value caching in Aquilia request handlers. Managed by the CacheProvider , it partitions cache keys by namespace to prevent key collisions across modules. Namespace Isolation Rather than mixing keys in a single flat database namespace (which leads to key collisions and complex prefixing logic), the CacheEffect partitions operations. By requesting a namespace at initialization (e.g. CacheEffect("products")), the handle transparently prefixes all operations, keeping caching logic localized. Resource Handles Depending on the system state, the CacheProvider yields one of two resource handles: CacheServiceHandle Acquired when the caching integration is enabled. It forwards operations to a central, DI-injected CacheService connected to Redis or Memcached. CacheHandle A fallback handle backed by a standard Python dictionary. Used during unit testing or when the main cache backend is unconfigured, ensuring handlers run without throwing connection exceptions. API Reference Both handles expose the same core async methods, making tests consistent with production: await handle.get(key: str) -> Any | None Retrieves the deserialized cache value. Returns None on a cache miss. await handle.set(key: str, value: Any, ttl: int | None = None) -> None Stores the value inside the namespace. Accepts an optional TTL (in seconds) that defaults to the config value if omitted. await handle.delete(key: str) -> bool Deletes the value matching the key from the namespace. Returns True if the key existed and was deleted, False otherwise. Usage: Cache-Aside with Automatic Invalidation The example below demonstrates retrieving a user's permissions and profile metadata from cache, falling back to a database transaction on a miss, and caching it. We also show how to invalidate the cache key when updating user permissions: from aquilia.controller import Controller, GET, PATCH, RequestCtx from aquilia.flow import requires from aquilia.effects import CacheEffect, DBTx class SecurityController(Controller): # Require both cache and db transaction capabilities effects = [ CacheEffect(namespace="permissions"), DBTx["write"] # Write required for update, used as read for retrieve ] @GET("/users/:id/permissions") async def get_permissions(self, id: int, ctx: RequestCtx) -> dict: cache = ctx.get_effect("Cache") db = ctx.get_effect("DBTx") # 1. Attempt to load from the namespaced permissions cache cache_key = f"user: :roles" roles = await cache.get(cache_key) if roles is None: # 2. Cache Miss - Fetch from Database roles = await db.fetch_all( "SELECT role_name FROM user_roles WHERE user_id = ?", (id,) ) # Normalize to basic dictionary list for serialization roles = [dict(r) for r in roles] # 3. Cache results for 1 hour await cache.set(cache_key, roles, ttl=3600) return ctx.json( ) @PATCH("/users/:id/permissions") async def update_permissions(self, id: int, ctx: RequestCtx) -> dict: body = await ctx.json() cache = ctx.get_effect("Cache") db = ctx.get_effect("DBTx") # 1. Update roles in DB await db.execute("DELETE FROM user_roles WHERE user_id = ?", (id,)) await db.execute_many( "INSERT INTO user_roles (user_id, role_name) VALUES (?, ?)", [(id, role) for role in body["roles"]] ) # 2. Invalidate cache key to ensure subsequent requests load fresh state cache_key = f"user: :roles" await cache.delete(cache_key) return ctx.json( ) DBTx Effect Queue Effect )

### Code Examples
```python
await handle.get(key: str) -> Any | None
```

```python
await handle.set(key: str, value: Any, ttl: int | None = None) -> None
```

```python
await handle.delete(key: str) -> bool
```



---

## Queue & Task Effects
**URL**: `https://tubox.cloud/docs/subsystem/queue`

EFFECTS / QUEUE & TASKS Queue & Task Effects The QueueEffect provides messaging capability inside route handlers. It can pub/sub events to standard brokers via the QueueProvider or enqueue async background tasks via the TaskQueueProvider . Message Queue Publishing When wired with the standard QueueProvider , the effect returns a QueueHandle . This handle facilitates publishing messages to brokers like Redis Streams or RabbitMQ. During testing, it falls back to collecting messages in an in-memory list. QueueHandle API await handle.publish(payload: Any, *, headers: dict[str, str] | None = None) -> None Publishes a single event payload to the configured topic, attaching optional metadata headers. await handle.publish_batch(payloads: Sequence[Any]) -> None Publishes a list of payloads sequentially, optimizing connection roundtrips. from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from aquilia.effects import QueueEffect class TelemetryIngestController(Controller): # Require Queue capability scoped to the "telemetry" topic effects = [QueueEffect("device_metrics")] @POST("/ingest/metrics") async def ingest_device_data(self, ctx: RequestCtx) -> dict: body = await ctx.json() queue = ctx.get_effect("Queue") # QueueHandle instance # Format payload and headers for real-world RabbitMQ/Redis Broker ingestion payload = await queue.publish( payload, headers= ) return Background Task Worker Integration When registered as a TaskQueueProvider , the effect hooks directly into Aquilia's background worker system. Rather than executing logic inside the HTTP request loop, it allows handlers to defer complex, resource-heavy operations (e.g. sending transaction emails or running AI inference models) to worker processes. It yields a request-scoped TaskQueueHandle that exposes the enqueue method. TaskQueueHandle API await handle.enqueue(func: Any, *args: Any, **kwargs: Any) -> str Submits an asynchronous function or task import path to the queue. Returns the unique Job ID. await handle.publish(payload: Any, *, headers: dict | None = None) -> None Compatibility no-op method designed to make the handle interchangeable with QueueHandle. from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from aquilia.effects import QueueEffect class RegistrationController(Controller): # Triggers task queue handle acquisition effects = [QueueEffect("default")] @POST("/register/corporate") async def register_company(self, ctx: RequestCtx) -> dict: body = await ctx.json() task_queue = ctx.get_effect("Queue") # TaskQueueHandle instance # Dispatch background worker chain (invoice rendering + email delivery) job_id = await task_queue.enqueue( "modules.billing.tasks:process_corporate_enrollment", company_id=body["company_id"], plan_tier=body["plan_tier"], billing_email=body["billing_email"] ) return Cache Effect HTTP Effect )

### Code Examples
```python
await handle.publish(payload: Any, *, headers: dict[str, str] | None = None) -> None
```

```python
await handle.publish_batch(payloads: Sequence[Any]) -> None
```

```python
from aquilia.controller import Controller, POST, RequestCtx
from aquilia.flow import requires
from aquilia.effects import QueueEffect

class TelemetryIngestController(Controller):
    # Require Queue capability scoped to the "telemetry" topic
    effects = [QueueEffect("device_metrics")]

    @POST("/ingest/metrics")
    async def ingest_device_data(self, ctx: RequestCtx) -> dict:
        body = await ctx.json()
        queue = ctx.get_effect("Queue")  # QueueHandle instance
        
        # Format payload and headers for real-world RabbitMQ/Redis Broker ingestion
        payload = {
            "device_id": body["device_id"],
            "temperature": float(body["temp"]),
            "humidity": float(body["humidity"]),
            "timestamp": body["timestamp"]
        }
        
        await queue.publish(
            payload,
            headers={
                "schema_version": "1.4.0",
                "environment": "production",
                "tenant_id": ctx.state.get("tenant_id", "default")
            }
        )
        return {"status": "metrics_dispatched_to_broker"}
```



---

## HTTP Client Effect
**URL**: `https://tubox.cloud/docs/subsystem/http`

EFFECTS / OUTBOUND HTTP HTTP Client Effect The HTTPEffect provides pre-configured, request-scoped outbound HTTP clients. Backed by the HTTPProvider and Aquilia's native HTTP client, it optimizes connection reuse, manages request timeouts, and handles connection pooling. Unified HTTP Connections Spawning arbitrary HTTP sessions (e.g. using standard library clients or raw requests libraries) per request degrades server throughput and risks socket exhaustion. The HTTPEffect integrates outbound queries into the ASGI lifecycle. Outbound connections share pooled HTTP sessions, enforce unified timeouts, and simplify key management. HTTPHandle API The acquired handle is an instance of HTTPHandle , which automatically parses JSON responses: await handle.get(url: str, **kwargs) -> Any Performs an async HTTP GET request. The URL path is appended to the provider's base URL. Returns decoded JSON. await handle.post(url: str, *, json: Any = None, **kwargs) -> Any Performs an async HTTP POST request, forwarding the json payload. Returns decoded JSON. await handle.put(url: str, *, json: Any = None, **kwargs) -> Any Performs an async HTTP PUT request, forwarding the json payload. Returns decoded JSON. await handle.delete(url: str, **kwargs) -> Any Performs an async HTTP DELETE request. Returns decoded JSON. Usage: Stripe Billing Sync The example below demonstrates querying the Stripe Billing API to check subscription details and issue invoice charge triggers: from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from aquilia.effects import HTTPEffect, DBTx class StripeBillingController(Controller): # Require HTTP client capability and database access effects = [ HTTPEffect(service="stripe"), DBTx["write"] ] @POST("/billing/sync-subscription") async def sync_stripe_subscription(self, ctx: RequestCtx) -> dict: http = ctx.get_effect("HTTP") # HTTPHandle instance db = ctx.get_effect("DBTx") # DBTxHandle instance body = await ctx.json() # 1. Fetch live subscription stats from Stripe API stripe_sub = await http.get( f"/v1/subscriptions/ ", headers= "} ) # 2. Check if subscription is unpaid if stripe_sub.get("status") == "unpaid": # 3. Trigger immediate payment charge retries via POST API charge_response = await http.post( f"/v1/invoices/ /pay", headers= "} ) # Update local DB account status to flagged await db.execute( "UPDATE billing_accounts SET status = ? WHERE stripe_customer_id = ?", ("FLAGGED", stripe_sub["customer"]) ) return ctx.json( ) return ctx.json( ) Queue Effect Storage Effect )

### Code Examples
```python
await handle.get(url: str, **kwargs) -> Any
```

```python
await handle.post(url: str, *, json: Any = None, **kwargs) -> Any
```

```python
await handle.put(url: str, *, json: Any = None, **kwargs) -> Any
```



---

## Storage Effect
**URL**: `https://tubox.cloud/docs/subsystem/storage`

EFFECTS / UNIFIED STORAGE Storage Effect The StorageEffect provides unified file and object storage operations. Managed by the StorageProvider , it abstracts filesystem locations and cloud storage backends (AWS S3, Google Cloud Storage, Azure Blobs) into a standard API. Storage Abstraction Layer Hardcoding file paths or importing third-party cloud SDKs directly into handlers ties your application logic to a specific cloud provider. The StorageEffect decouples this connection. Handlers operate on simple keys (e.g., "invoices/invoice_123.pdf") inside a scoped bucket namespace, leaving the backend storage configuration to the provider setup. StorageHandle API The acquired handle is an instance of StorageHandle . It manages binary data transfer safely across local filesystems and cloud buckets: await handle.read(key: str) -> bytes | None Reads file contents as raw bytes. Returns None if the file is missing or connection issues arise. await handle.write(key: str, data: bytes) -> None Writes raw bytes to the specified key. Overwrites existing contents if present. Automatically constructs directory trees if needed on a local filesystem. await handle.delete(key: str) -> bool Deletes the file matching the key. Returns True if deletion was successful, False otherwise. await handle.exists(key: str) -> bool Queries the backend to check if a file exists under the key. Returns a boolean status. Usage: Profile Avatar Secure Uploader The example below demonstrates receiving a profile avatar, generating a unique filename, writing it to S3 via the StorageHandle , and saving the record reference to the database: import uuid from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from aquilia.effects import StorageEffect, DBTx class AvatarUploadController(Controller): # Require both storage bucket access and database transaction effects = [ StorageEffect("user-avatars"), DBTx["write"] ] @POST("/profile/avatar") async def upload_avatar(self, ctx: RequestCtx) -> dict: storage = ctx.get_effect("Storage") # StorageHandle instance db = ctx.get_effect("DBTx") # DBTxHandle instance # 1. Fetch file from multipart request body uploaded_file = await ctx.request.file("avatar") if not uploaded_file: return ctx.json( , status=400) # 2. Validate file extension ext = uploaded_file.filename.split(".")[-1].lower() if ext not in ("jpg", "jpeg", "png", "webp"): return ctx.json( , status=400) # 3. Generate a secure, unique filename key secure_key = f"profiles/ / . " # 4. Write bytes to the cloud storage bucket await storage.write(secure_key, uploaded_file.content) # 5. Update user avatar reference in database await db.execute( "UPDATE profiles SET avatar_path = ? WHERE user_id = ?", (secure_key, ctx.user.id) ) return HTTP Effect Custom Effects )

### Code Examples
```python
await handle.read(key: str) -> bytes | None
```

```python
await handle.write(key: str, data: bytes) -> None
```

```python
await handle.delete(key: str) -> bool
```



---

## Custom Effects & Providers
**URL**: `https://tubox.cloud/docs/subsystem/custom`

EFFECTS / CUSTOM EFFECTS Custom Effects & Providers Aquilia's Effect system is open and fully extensible. By subclassing Effect and EffectProvider , you can declare custom infrastructural integrations (e.g. SMTP clients, payment gateways, or AI models) and inject them safely into request contexts. Step-by-Step Implementation To extend the capability system, you must define three items: Effect Token: A subclass of Effect representing the typed capability tag. Resource Handle: A class wrapping the provider client. Handlers interact with this handle inside the request context. Effect Provider: A subclass of EffectProvider managing the connection, setup, and cleanup lifecycle. Code Implementation (Slack Dispatcher) Here is how to create a custom SlackEffect that pools HTTPS webhook client sessions, formats slack block payloads, and manages channel routing: import aiohttp from typing import Any, dict from aquilia.effects import Effect, EffectProvider, EffectKind # 1. Define the Effect Token class SlackEffect(Effect[str]): def __init__(self, channel: str = "general"): super().__init__("Slack", mode=channel, kind=EffectKind.CUSTOM) # 2. Define the user-facing resource handle class SlackHandle: def __init__(self, session: aiohttp.ClientSession, webhook_url: str, channel: str): self.session = session self.webhook_url = webhook_url self.channel = channel async def send_message(self, text: str, blocks: list[dict] | None = None) -> None: payload = ", "text": text, "blocks": blocks or [] } async with self.session.post(self.webhook_url, json=payload) as resp: resp.raise_for_status() # 3. Define the Lifecycle Provider class SlackProvider(EffectProvider): def __init__(self, webhook_url: str): self.webhook_url = webhook_url self.session = None async def initialize(self) -> None: # Invoked once at server startup: initialize shared async HTTP session self.session = aiohttp.ClientSession() async def acquire(self, mode: str | None = None) -> SlackHandle: # Invoked per-request: return a handle scoped to the requested channel mode channel = mode or "general" return SlackHandle(self.session, self.webhook_url, channel) async def release(self, resource: SlackHandle, success: bool = True) -> None: # Invoked per-request end: nothing to tear down since session is pooled pass async def finalize(self) -> None: # Invoked once at server shutdown: safely close async HTTP session if self.session: await self.session.close() async def health_check(self) -> dict[str, Any]: if not self.session or self.session.closed: return return Provider Registration You can register your custom provider with the EffectRegistry during application startup: from aquilia.effects import EffectRegistry from extensions.slack_effect import SlackProvider # Create or fetch registry registry = EffectRegistry() # Register custom provider with Slack webhook URL configuration registry.register("Slack", SlackProvider(webhook_url="https://hooks.slack.com/services/T00/B00/X00")) Using in Controllers Once registered, require the capability by name. The handle will be automatically acquired and injected into the context: from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import requires from extensions.slack_effect import SlackEffect class SlackNotificationController(Controller): # Require Slack capability scoped to the "incidents" channel effects = [SlackEffect("incidents")] @POST("/notify/incident") async def dispatch_incident(self, ctx: RequestCtx) -> dict: slack = ctx.get_effect("Slack") # SlackHandle instance # Dispatch formatted alert block await slack.send_message( text="ALERT: Incident detected in server-prod-04", blocks=[ } ] ) return Storage Effect )

### Code Examples
```python
import aiohttp
from typing import Any, dict
from aquilia.effects import Effect, EffectProvider, EffectKind

# 1. Define the Effect Token
class SlackEffect(Effect[str]):
    def __init__(self, channel: str = "general"):
        super().__init__("Slack", mode=channel, kind=EffectKind.CUSTOM)

# 2. Define the user-facing resource handle
class SlackHandle:
    def __init__(self, session: aiohttp.ClientSession, webhook_url: str, channel: str):
        self.session = session
        self.webhook_url = webhook_url
        self.channel = channel

    async def send_message(self, text: str, blocks: list[dict] | None = None) -> None:
        payload = {
            "channel": f"#{self.channel}",
            "text": text,
            "blocks": blocks or []
        }
        async with self.session.post(self.webhook_url, json=payload) as resp:
            resp.raise_for_status()

# 3. Define the Lifecycle Provider
class SlackProvider(EffectProvider):
    def __init__(self, webhook_url: str):
        self.webhook_url = webhook_url
        self.session = None

    async def initialize(self) -> None:
        # Invoked once at server startup: initialize shared async HTTP session
        self.session = aiohttp.ClientSession()

    async def acquire(self, mode: str | None = None) -> SlackHandle:
        # Invoked per-request: return a handle scoped to the requested channel mode
        channel = mode or "general"
        return SlackHandle(self.session, self.webhook_url, channel)

    async def release(self, resource: SlackHandle, success: bool = True) -> None:
        # Invoked per-request end: nothing to tear down since session is pooled
        pass

    async def finalize(self) -> None:
        # Invoked once at server shutdown: safely close async HTTP session
        if self.session:
            await self.session.close()

    async def health_check(self) -> dict[str, Any]:
        if not self.session or self.session.closed:
            return {"healthy": False, "reason": "HTTP session is closed"}
        return {"healthy": True}
```

```python
from aquilia.effects import EffectRegistry
from extensions.slack_effect import SlackProvider

# Create or fetch registry
registry = EffectRegistry()

# Register custom provider with Slack webhook URL configuration
registry.register("Slack", SlackProvider(webhook_url="https://hooks.slack.com/services/T00/B00/X00"))
```

```python
from aquilia.controller import Controller, POST, RequestCtx
from aquilia.flow import requires
from extensions.slack_effect import SlackEffect

class SlackNotificationController(Controller):
    # Require Slack capability scoped to the "incidents" channel
    effects = [SlackEffect("incidents")]

    @POST("/notify/incident")
    async def dispatch_incident(self, ctx: RequestCtx) -> dict:
        slack = ctx.get_effect("Slack")  # SlackHandle instance
        
        # Dispatch formatted alert block
        await slack.send_message(
            text="ALERT: Incident detected in server-prod-04",
            blocks=[
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": "*ALERT:* Critical incident detected on *server-prod-04*. CPU utilization > 98%."
                    }
                }
            ]
        )
        return {"status": "slack_notification_dispatched"}
```



---

## Flow Pipelines
**URL**: `https://tubox.cloud/docs/subsystem/pipelines`

SUBSYSTEM / FLOW PIPELINES Flow Pipelines The FlowPipeline class compiles and executes a sequence of execution nodes under strict priority bands. It acts as the backbone of request execution and route-specific middleware, orchestrating capability acquisition and safe resource release. Pipeline Anatomy & Execution A pipeline structures your request processing into discrete, composable phases: 1. Guards: Run first to perform security checks, access control, and rate limiting. If a guard returns False or a Response, execution short-circuits. 2. Transforms: Modify request parameters, deserialize payloads, and thread state changes into the context. 3. Effect Acquisition: Automatically lease resource handles from the registry for any capabilities required by subsequent nodes. 4. Handler: Executes core business logic. A pipeline can have exactly one primary handler. 5. Hooks (Post-Handler): Execute post-processing, logging, metrics collection, and can optionally modify the handler's return value. Priority Bands When nodes are added to a pipeline, they are sorted first by their node type band, and then by their individual numeric priority. Aquilia defines standard priority bands as constant integers: PRIORITY_CRITICAL = 10 # Security checks, CORS validation, global rate limiting. PRIORITY_AUTH = 20 # Authentication guards, session lookups, permission validations. PRIORITY_VALIDATE = 30 # Input validation schema checks (Contracts). PRIORITY_TRANSFORM = 40 # Payload transformations, parameter binding. PRIORITY_DEFAULT = 50 # Primary request handler execution. PRIORITY_ENRICH = 60 # Response enrichment, wrapping structures. PRIORITY_LOG = 70 # Audit log generation, performance metrics emission. PRIORITY_CLEANUP = 80 # Post-request teardowns, resource recycling. API Builder Reference def pipeline(name: str = "pipeline", *, timeout: float | None = None) -> FlowPipeline Helper function that instantiates a new FlowPipeline builder. .guard(node, *, name: str | None = None, priority: int = 20, effects: list[str] | None = None, condition: Callable | None = None) Adds a guard node to the pipeline. Guards return True to proceed, or False/a Response to short-circuit. .transform(node, *, name: str | None = None, priority: int = 40, effects: list[str] | None = None) Adds a transformation node that runs after guards. Modifies or enriches context variables. .handler(node, *, name: str | None = None, priority: int = 50, effects: list[str] | None = None) Sets the main execution handler. Receives the context and yields the core response value. .hook(node, *, name: str | None = None, priority: int = 70, effects: list[str] | None = None) Registers post-execution hooks to log telemetry or adjust the resolved response. .compose(*other: FlowPipeline) -> FlowPipeline Merges nodes from multiple pipelines, returning a new pipeline with all nodes sorted by priority. Can also be invoked using the | operator. from_pipeline_list(nodes: Sequence[Any], *, name: str) -> FlowPipeline Utility converting controller pipeline lists into a unified FlowPipeline . Automatically materializes zero-argument factory functions. Building & Executing Pipelines Below is a detailed guide showing how to create a pipeline manually, compose it with operators, and trigger execution within a request context. from aquilia.flow import pipeline, FlowContext, requires from aquilia.response import Response # 1. Define nodes async def check_api_key(ctx: FlowContext): api_key = ctx.request.headers.get("X-API-Key") if api_key != "secret-token": # Returning a Response short-circuits execution return Response.json( , status=401) return True async def sanitize_payload(ctx: FlowContext): # Transforms modify state dictionaries in context if "email" in ctx.state: ctx.state["email"] = ctx.state["email"].strip().lower() @requires("DBTx") async def save_record(ctx: FlowContext): # Automatically acquired DB connection db = ctx.get_effect("DBTx") await db.execute( "INSERT INTO leads (email) VALUES (?)", (ctx.state["email"],) ) return # 2. Build Pipeline lead_pipeline = ( pipeline("create_lead") .guard(check_api_key, priority=10) .transform(sanitize_payload) .handler(save_record) ) # 3. Execute Pipeline # registry contains registered EffectProviders (e.g. DBTxProvider) ctx = FlowContext(request=request, state= ) result = await lead_pipeline.execute(ctx, effect_registry=registry) if result.is_success: print(f"Success! Response: ") elif result.is_guarded: print(f"Guarded (Short-circuited): ") Controller Integrations & Composition You can compose pipelines using the bitwise OR (|) operator. This allows you to define reusable segments (e.g., auth checks) and merge them with route-specific handlers. from aquilia.controller import Controller, POST, RequestCtx from aquilia.flow import pipeline, requires # Reusable security segment auth_pipeline = pipeline("auth_guard").guard(verify_jwt, priority=10) class UserController(Controller): # Controller routes accept pipeline lists @POST( "/users", pipeline=[ auth_pipeline, # Reusable pipeline validate_user_schema, # Plain function (wraps as guard) ] ) @requires("DBTx") async def create_user(self, ctx: RequestCtx) -> dict: # Executes within the compiled pipeline context db = ctx.get_effect("DBTx") ... return Overview Flow Context & Nodes )

### Code Examples
```python
PRIORITY_CRITICAL  = 10  # Security checks, CORS validation, global rate limiting.
PRIORITY_AUTH      = 20  # Authentication guards, session lookups, permission validations.
PRIORITY_VALIDATE  = 30  # Input validation schema checks (Contracts).
PRIORITY_TRANSFORM = 40  # Payload transformations, parameter binding.
PRIORITY_DEFAULT   = 50  # Primary request handler execution.
PRIORITY_ENRICH    = 60  # Response enrichment, wrapping structures.
PRIORITY_LOG       = 70  # Audit log generation, performance metrics emission.
PRIORITY_CLEANUP   = 80  # Post-request teardowns, resource recycling.
```

```python
def pipeline(name: str = "pipeline", *, timeout: float | None = None) -> FlowPipeline
```

```python
.guard(node, *, name: str | None = None, priority: int = 20, effects: list[str] | None = None, condition: Callable | None = None)
```



---

## Flow Context & Nodes
**URL**: `https://tubox.cloud/docs/subsystem/context-nodes`

SUBSYSTEM / CONTEXT & NODES Flow Context & Nodes Deep-dive into the data carriers and execution units of the Flow system. Learn how FlowContext threads state and resources through FlowNode pipelines, returning detailed execution results. FlowContext Anatomy The FlowContext threads execution state, request parameters, dependency containers, and acquired effect resources through every stage of the pipeline. class FlowContext: request: Any # The raw ASGI/HTTP request context (e.g. RequestCtx). container: Any # The request-scoped dependency injection container. state: dict[str, Any] # Arbitrary mutable key-value storage used by transforms and handlers. identity: Any # The authenticated principal, typically resolved and set by auth guards. session: Any # Active session state proxy if session middleware is active. effects: dict[str, Any] # Acquired capability resource handles (e.g. database transaction, cache client). metadata: dict[str, Any] # Telemetry logs tracking timings, executed node traces, and acquired effects. Context Method Reference def get_effect(self, name: str) -> Any: Retrieves an acquired capability resource. If the resource is not active, it throws an EffectNotAcquiredFault. Supports type overloading for standard effects. def has_effect(self, name: str) -> bool: Returns whether the specified effect capability is currently acquired and bound to the context. def add_cleanup(self, callback: Callable[[], Awaitable[None]]) -> None: Registers an asynchronous teardown callback. Cleanup actions are executed in Last-In-First-Out (LIFO) order during pipeline disposal. def dispose(self) -> None: Drives the execution of all registered cleanup callbacks, ensuring database transactions roll back or temp files clean up on pipeline failure. Flow Nodes & Node Types A FlowNode represents a single callable unit in a pipeline. The pipeline compiler parses callables, extracts decorator metadata, and maps them to concrete nodes: class FlowNodeType(Enum): GUARD = "guard" # Short-circuits execution (e.g. auth / input validation). TRANSFORM = "transform" # Modifies request parameters or updates context state. HANDLER = "handler" # Core business logic method (usually a controller route). HOOK = "hook" # Post-processing hooks running after the main handler. EFFECT = "effect" # Managed capability resources acquired lazily. MIDDLEWARE = "middleware" # Wraps the entire execution chain. Declaring Requirements with @requires The @requires decorator binds capability metadata directly onto the decorated callable function. When a pipeline executes, it crawls the node list, inspects the callables for the __flow_effects__ property, and triggers batch acquisition before the handler runs. from aquilia.flow import requires, FlowContext @requires("DBTx", "Cache") async def process_payment(ctx: FlowContext): # Retrieve capabilities safely db = ctx.get_effect("DBTx") cache = ctx.get_effect("Cache") # execute database queries user_id = ctx.state["user_id"] balance = await db.fetch_val("SELECT balance FROM accounts WHERE user_id = ?", (user_id,)) ... return FlowResult & Execution Outcomes Triggering execute() returns a structured FlowResult instance representing the final state: class FlowStatus(Enum): SUCCESS = "success" # Completed successfully; result.value contains the handler output. GUARDED = "guarded" # Short-circuited by a guard; result.guard contains the guard node. ERROR = "error" # Unhandled exception raised; result.error contains the exception. TIMEOUT = "timeout" # Execution duration exceeded configured timeout limit. CANCELLED = "cancelled" # Pipeline task cancelled before completion. Context Cleanup Callback Flow You can register custom teardown code directly onto the context. This guarantees cleanup runs even if subsequent nodes throw errors or timeout: import os from aquilia.flow import FlowContext, FlowError async def write_temp_file(ctx: FlowContext): temp_path = f"/tmp/process_ .json" # 1. Write initial payload with open(temp_path, "w") as f: f.write(ctx.state["payload"]) # 2. Register callback to delete file on teardown async def cleanup_temp(): if os.path.exists(temp_path): os.remove(temp_path) ctx.add_cleanup(cleanup_temp) ctx.state["temp_file"] = temp_path # Teardown triggers LIFO order # await ctx.dispose() Flow Pipelines Layers & Compositions )

### Code Examples
```python
class FlowContext:
    request: Any            # The raw ASGI/HTTP request context (e.g. RequestCtx).
    container: Any          # The request-scoped dependency injection container.
    state: dict[str, Any]   # Arbitrary mutable key-value storage used by transforms and handlers.
    identity: Any           # The authenticated principal, typically resolved and set by auth guards.
    session: Any            # Active session state proxy if session middleware is active.
    effects: dict[str, Any] # Acquired capability resource handles (e.g. database transaction, cache client).
    metadata: dict[str, Any] # Telemetry logs tracking timings, executed node traces, and acquired effects.
```

```python
def get_effect(self, name: str) -> Any:
```

```python
def has_effect(self, name: str) -> bool:
```



---

## Layers & Compositions
**URL**: `https://tubox.cloud/docs/subsystem/layers`

SUBSYSTEM / LAYERS & COMPOSITIONS Layers & Compositions Manage complex capability graph initialization using Layer and EffectScope . Decouple construction from usage, sort dependencies topologically, and acquire resources safely outside pipelines. The Layer Architecture In large microservice applications, capability providers (like database connection pools or cache servers) have complex initialization graphs. A database provider might depend on a configuration provider, while a metrics service might require both configuration and database logging connections. Inspired by Effect-TS, the Layer system allows you to build modular constructors that declare explicit dependencies. The framework's dependency compiler sorts these layers topologically at startup, resolving, building, and registering providers automatically. Layer API Reference class Layer: def __init__(self, name: str, factory: Callable, deps: list[str] = [], scope: str = "app") Constructs a composable layer. factory is a callable that receives resolved dependencies as keyword arguments and returns a provider. scope dictates whether the provider has application or request lifetime. @staticmethod def merge(*layers: Layer) -> LayerComposition Combines multiple layers into a unified composition. The compiler automatically resolves inter-layer dependencies and orders initialization topologically. @staticmethod def provide(layer: Layer, *providers: Layer) -> LayerComposition Expresses dependency injections explicitly. Builds the list of providers first, then feeds their constructed values as dependencies into the target layer. LayerComposition API Merging or chaining layers creates a LayerComposition. It manages sorting and mount operations: async def build_all(self, initial_deps: dict | None = None) -> dict[str, Any] Builds all layers in computed topological order. Returns a dictionary mapping capability names to constructed provider instances. Raises FlowError if circular dependencies are detected. async def register_with(self, registry: EffectRegistry, initial_deps: dict | None = None) -> None Builds all layers and mounts the output providers directly into the active EffectRegistry registry. Manual Capability Management: EffectScope While pipelines acquire capabilities automatically based on annotations, you can manage them manually using the EffectScope context manager. This is ideal for background tasks, CLI commands, or scripts that require scoped resource access: class EffectScope: def __init__(self, registry: EffectRegistry, effect_names: list[str], *, context = None, modes = None) Async context manager. On enter (__aenter__), it calls acquire() on all listed providers. On exit (__aexit__), it releases them, tracking whether exceptions occurred to trigger rollbacks or commits automatically. Topological Bootstrap Walkthrough The following code defines configuration, database, and cache capability layers. The layers are merged, resolved topologically, registered, and accessed inside an EffectScope . from aquilia.flow import Layer, EffectScope from aquilia.effects import EffectRegistry, DBTxProvider, CacheProvider # 1. Define capability layers config_layer = Layer( name="Config", factory=lambda: ) db_layer = Layer( name="DBTx", # Receives constructed config layer output as keyword argument 'Config' factory=lambda Config: DBTxProvider(Config["db_url"]), deps=["Config"] ) cache_layer = Layer( name="Cache", # Receives config output as 'Config' factory=lambda Config: CacheProvider(Config["cache_host"]), deps=["Config"] ) # 2. Merge Layers (Sorted Topologically: Config -> DBTx -> Cache) app_composition = Layer.merge(db_layer, cache_layer, config_layer) # 3. Mount providers to registry registry = EffectRegistry() await app_composition.register_with(registry) # 4. Access resources manually via EffectScope async def process_jobs(): async with EffectScope(registry, ["DBTx", "Cache"]) as effects: db = effects["DBTx"] cache = effects["Cache"] # Safe transaction execution await db.execute("UPDATE stats SET runs = runs + 1") await cache.set("last_run", "now") Flow Context & Nodes Built-in Effects )

### Code Examples
```python
class Layer:
    def __init__(self, name: str, factory: Callable, deps: list[str] = [], scope: str = "app")
```

```python
@staticmethod
def merge(*layers: Layer) -> LayerComposition
```

```python
@staticmethod
def provide(layer: Layer, *providers: Layer) -> LayerComposition
```



---

## Server-Sent Events (SSE)
**URL**: `https://tubox.cloud/docs/sse`

SSE SYSTEM / OVERVIEW Server-Sent Events (SSE) Unidirectional real-time server push for Aquilia applications. Learn how the SSE subsystem keeps connection channels open to stream updates dynamically over standard HTTP. What is SSE? Server-Sent Events (SSE) is a web technology enabling servers to push real-time event updates to clients over a single long-lived TCP connection. Defined as part of the HTML5 standard, it is natively supported by all modern browsers via the EventSource API. Unlike WebSockets, which are bi-directional and require custom handshake protocols, SSE operates over standard HTTP, making it simpler to deploy, compatible with HTTP/2 multiplexing, and highly resilient through automatic client-side reconnection. Aquilia SSE Architecture In Aquilia, SSE streams are managed by SSEResponse . When returned from a controller method, it binds an asynchronous event iterator directly into the ASGI server write pipeline. The server streams bytes chunk-by-chunk, flushing buffers immediately after each event is written. import asyncio from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse, SSEEvent class LiveController(Controller): @GET("/sse/stream") async def stream_live(self, ctx: RequestCtx): # Wraps an async generator yielding SSEEvent objects return SSEResponse(self._event_source()) async def _event_source(self): for i in range(5): yield SSEEvent(data=f"message ") await asyncio.sleep(1.0) Protocol Transport Headers To prevent proxies and browsers from buffering or caching events, the SSEResponse engine configures the following transport headers automatically: Content-Type: set to text/event-stream; charset=utf-8. Cache-Control: set to no-cache, no-transform to bypass intermediate proxy memory caches. Connection: set to keep-alive to instruct ASGI servers to preserve the request connection channel. X-Accel-Buffering: set to no. This tells Nginx to disable buffering and stream output immediately. Custom Effects Standard Events )

### Code Examples
```python
import asyncio
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse, SSEEvent

class LiveController(Controller):
    @GET("/sse/stream")
    async def stream_live(self, ctx: RequestCtx):
        # Wraps an async generator yielding SSEEvent objects
        return SSEResponse(self._event_source())

    async def _event_source(self):
        for i in range(5):
            yield SSEEvent(data=f"message {i}")
            await asyncio.sleep(1.0)
```



---

## Standard Events & Spec
**URL**: `https://tubox.cloud/docs/sse/standard`

SSE SYSTEM / STANDARD EVENTS Standard Events & Spec Understand the structure of SSEEvent , custom event namespaces, retry options, and client reconnection behaviors. SSEEvent Structure An SSEEvent represents a structured data payload formatted strictly according to the W3C Server-Sent Events specification. The properties of the class translate directly to fields in the event stream: class SSEEvent: data: str # The raw data payload. Splits multi-line strings automatically. id: str | None = None # Event identifier. Used by browsers to query missing events. event: str | None = None # Event name tag. Used on client to filter events. retry: int | None = None # Reconnect retry delay in milliseconds. Custom Event Filters By default, events pushed through an SSE stream have no event name, and are caught by the browser's generic onmessage handler. Specifying the event string parameter allows you to partition streams. The browser will then trigger specific event listeners registered for that name. import asyncio from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse, SSEEvent class FeedController(Controller): @GET("/sse/news") async def news_feed(self, ctx: RequestCtx): return SSEResponse(self._generate_feed()) async def _generate_feed(self): # Push to 'sports' listener yield SSEEvent(data="Local match won 3-1", event="sports") await asyncio.sleep(0.5) # Push to 'weather' listener yield SSEEvent(data="Heavy rain warning", event="weather") Reconnections & Caching (Last-Event-ID) When a connection drops (due to network changes or server restarts), the browser's `EventSource` client attempts to reconnect automatically. To prevent data loss, the client sends the last received event ID in the Last-Event-ID header. The server can read this header and stream missing logs starting from that ID. Using the retry parameter, the server can dynamically change the browser's reconnect cooldown interval. Consuming on the Client (JavaScript) Register event listeners on the browser client for custom namespaces: const eventSource = new EventSource('/sse/news'); // 1. Listen to the generic stream (unnamed events) eventSource.onmessage = (event) => ; // 2. Listen to custom namespace updates eventSource.addEventListener('sports', (event) => ); eventSource.addEventListener('weather', (event) => ); // 3. Handle connection errors eventSource.onerror = (err) => ; Overview Text & JSON Streams )

### Code Examples
```python
class SSEEvent:
    data: str               # The raw data payload. Splits multi-line strings automatically.
    id: str | None = None   # Event identifier. Used by browsers to query missing events.
    event: str | None = None # Event name tag. Used on client to filter events.
    retry: int | None = None # Reconnect retry delay in milliseconds.
```

```python
import asyncio
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse, SSEEvent

class FeedController(Controller):
    @GET("/sse/news")
    async def news_feed(self, ctx: RequestCtx):
        return SSEResponse(self._generate_feed())

    async def _generate_feed(self):
        # Push to 'sports' listener
        yield SSEEvent(data="Local match won 3-1", event="sports")
        await asyncio.sleep(0.5)
        
        # Push to 'weather' listener
        yield SSEEvent(data="Heavy rain warning", event="weather")
```

```python
const eventSource = new EventSource('/sse/news');

// 1. Listen to the generic stream (unnamed events)
eventSource.onmessage = (event) => {
    console.log("Generic message:", event.data);
};

// 2. Listen to custom namespace updates
eventSource.addEventListener('sports', (event) => {
    console.log("Sports flash:", event.data);
});

eventSource.addEventListener('weather', (event) => {
    console.log("Weather update:", event.data);
});

// 3. Handle connection errors
eventSource.onerror = (err) => {
    console.error("Stream error occurred:", err);
};
```



---

## Text & JSON Streaming
**URL**: `https://tubox.cloud/docs/sse/streams`

SSE SYSTEM / TEXT & JSON STREAMS Text & JSON Streaming Stream tokens or serializable payloads without wrapping elements manually. Leverage the SSEResponse.text() and SSEResponse.json() constructor overloads. SSEResponse.text() When streaming simple character files, LLM completion tokens, or raw console logs, wrapping strings inside SSEEvent objects is verbose. The SSEResponse.text() constructor accepts an AsyncGenerator[str, None]. It intercepts each string output from the generator, wraps it in a standard event payload, and writes it directly to the response socket. import asyncio from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse class LogStreamController(Controller): @GET("/sse/logs") async def stream_logs(self, ctx: RequestCtx): # Simply returns the text-based generator return SSEResponse.text(self._log_generator()) async def _log_generator(self): for line in ["Initialize boot...", "Load integrations...", "Compile routes..."]: yield line + "\\n" await asyncio.sleep(0.5) SSEResponse.json() For richer dashboards, updates must often be structured JSON payloads. Manual JSON encoding within generator functions adds boilerplates and risks runtime faults. The SSEResponse.json() constructor takes an AsyncGenerator[Any, None]. Each object yielded is encoded using json.dumps() and sent as an event. If serialization fails, the stream throws an SSESerializationFault . import asyncio from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse class IngestController(Controller): @GET("/sse/ingest/status") async def ingest_status(self, ctx: RequestCtx): # Returns the JSON object generator return SSEResponse.json(self._generate_status()) async def _generate_status(self): yield await asyncio.sleep(0.8) yield await asyncio.sleep(0.8) yield Standard Events OpenAI Streaming )

### Code Examples
```python
import asyncio
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse

class LogStreamController(Controller):
    @GET("/sse/logs")
    async def stream_logs(self, ctx: RequestCtx):
        # Simply returns the text-based generator
        return SSEResponse.text(self._log_generator())

    async def _log_generator(self):
        for line in ["Initialize boot...", "Load integrations...", "Compile routes..."]:
            yield line + "\\n"
            await asyncio.sleep(0.5)
```

```python
import asyncio
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse

class IngestController(Controller):
    @GET("/sse/ingest/status")
    async def ingest_status(self, ctx: RequestCtx):
        # Returns the JSON object generator
        return SSEResponse.json(self._generate_status())

    async def _generate_status(self):
        yield {"step": "read", "rows": 1200, "status": "processing"}
        await asyncio.sleep(0.8)
        yield {"step": "validate", "rows": 1200, "status": "processing"}
        await asyncio.sleep(0.8)
        yield {"step": "done", "rows": 1200, "status": "completed"}
```



---

## AI Streaming with OpenAI
**URL**: `https://tubox.cloud/docs/sse/openai`

SSE SYSTEM / OPENAI STREAMING AI Streaming with OpenAI Implement real-time ChatGPT-style chat streaming by connecting OpenAI's async client stream to Aquilia's SSEResponse engine. Scenario Integration When building generative AI interfaces, displaying completion blocks after a long wait ruins the user experience. By streaming individual response tokens as they are generated by models (like gpt-4o), the page feels instantaneous. This scenario demonstrates how to invoke OpenAI's asynchronous stream API inside an Aquilia controller method, capture tokens sequentially, and tunnel them directly to client browsers using SSEResponse.text . Backend Controller The controller action reads the prompt parameter, initializes the async OpenAI client, and returns a token generator stream: import os from openai import AsyncOpenAI from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse class OpenAIChatController(Controller): def initialize(self): # Initialize OpenAI async client self.client = AsyncOpenAI(api_key=os.environ.get("OPENAI_API_KEY")) @GET("/sse/chat") async def chat_stream(self, ctx: RequestCtx): prompt = ctx.query.get("prompt", "Tell me a joke.") # Stream response back to the client return SSEResponse.text(self._openai_token_generator(prompt)) async def _openai_token_generator(self, prompt: str): # Request completion stream from OpenAI API stream = await self.client.chat.completions.create( model="gpt-4", messages=[ ], stream=True ) # Iterate over stream chunks asynchronously and yield content async for chunk in stream: token = chunk.choices[0].delta.content or "" if token: yield token Frontend Client Integration On the browser side, query the chat stream endpoint and append tokens to your DOM elements: function startChatStream(userPrompt) \`); eventSource.onmessage = (event) => ; eventSource.onerror = (error) => ; } Text & JSON Streams Resource Management )

### Code Examples
```python
import os
from openai import AsyncOpenAI
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse

class OpenAIChatController(Controller):
    def initialize(self):
        # Initialize OpenAI async client
        self.client = AsyncOpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

    @GET("/sse/chat")
    async def chat_stream(self, ctx: RequestCtx):
        prompt = ctx.query.get("prompt", "Tell me a joke.")
        
        # Stream response back to the client
        return SSEResponse.text(self._openai_token_generator(prompt))

    async def _openai_token_generator(self, prompt: str):
        # Request completion stream from OpenAI API
        stream = await self.client.chat.completions.create(
            model="gpt-4",
            messages=[{"role": "user", "content": prompt}],
            stream=True
        )
        
        # Iterate over stream chunks asynchronously and yield content
        async for chunk in stream:
            token = chunk.choices[0].delta.content or ""
            if token:
                yield token
```

```python
function startChatStream(userPrompt) {
    const chatContainer = document.getElementById("chat-box");
    const encodedPrompt = encodeURIComponent(userPrompt);
    
    // Connect to Aquilia SSE Chat endpoint
    const eventSource = new EventSource(`/sse/chat?prompt=${encodedPrompt}`);

    eventSource.onmessage = (event) => {
        // Append tokens dynamically to container
        chatContainer.innerText += event.data;
    };

    eventSource.onerror = (error) => {
        console.log("Chat connection complete or disconnected.");
        eventSource.close();
    };
}
```



---

## Resource & Disconnect Management
**URL**: `https://tubox.cloud/docs/sse/resources`

SSE SYSTEM / RESOURCE MANAGEMENT Resource & Disconnect Management Prevent connection and file handle leaks in long-lived SSE streams. Manage client disconnects and clean up resources safely. Client Disconnect Mechanics Because Server-Sent Events can stream indefinitely, clients frequently close their connections abruptly (e.g. by closing the browser tab, navigating away, or experiencing a network dropout). When a connection is severed, the ASGI server fails to write the next byte chunk and terminates the handler task. In Python's asyncio, this triggers a task cancellation, raising an asyncio.CancelledError inside the active generator function. Failure to handle this cancellation will cause leased databases, connection pools, or file descriptors to remain open, leading to leakages. Safe Generator Pattern To guarantee cleanup operations execute, always wrap your streaming loop inside a try...finally statement. When the task is cancelled, control flows automatically into the finally block: import asyncio from aquilia.controller import Controller, GET, RequestCtx from aquilia.sse import SSEResponse, SSEEvent class SafeController(Controller): @GET("/sse/safe-metrics") async def get_metrics(self, ctx: RequestCtx): return SSEResponse(self._stream_safely()) async def _stream_safely(self): # 1. Acquire connection or lock db_connection = await self.db_pool.acquire() try: while True: data = await db_connection.fetch_row("SELECT * FROM metrics ORDER BY id DESC LIMIT 1") yield SSEEvent(data=str(data)) await asyncio.sleep(2.0) except asyncio.CancelledError: # Caught automatically when browser closes connection print("Stream cancelled: Client disconnected.") raise finally: # 2. Guarantee releasing connection back to pool await self.db_pool.release(db_connection) print("Successfully released DB connection.") Configuring Stream Timeouts Allowing streams to run indefinitely is a security risk and can lead to resources drying up. You can configure a maximum lifetime for your streams by passing the timeout parameter to SSEResponse (measured in seconds). Once the timeout is reached, the response completes, and the client receives a finished connection. The browser will then trigger automatic reconnection according to spec. OpenAI Streaming Built-in Effects )

### Code Examples
```python
import asyncio
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.sse import SSEResponse, SSEEvent

class SafeController(Controller):
    @GET("/sse/safe-metrics")
    async def get_metrics(self, ctx: RequestCtx):
        return SSEResponse(self._stream_safely())

    async def _stream_safely(self):
        # 1. Acquire connection or lock
        db_connection = await self.db_pool.acquire()
        try:
            while True:
                data = await db_connection.fetch_row("SELECT * FROM metrics ORDER BY id DESC LIMIT 1")
                yield SSEEvent(data=str(data))
                await asyncio.sleep(2.0)
        except asyncio.CancelledError:
            # Caught automatically when browser closes connection
            print("Stream cancelled: Client disconnected.")
            raise
        finally:
            # 2. Guarantee releasing connection back to pool
            await self.db_pool.release(db_connection)
            print("Successfully released DB connection.")
```



---

## Cryptographic Signing Overview
**URL**: `https://tubox.cloud/docs/signing`

SIGNING SYSTEM / OVERVIEW Cryptographic Signing Overview Secure data payload transit across untrusted environments. Learn about Aquilia's zero-dependency, OWASP-aligned cryptographic signing subsystem. Core Design Principles The signing subsystem allows Aquilia applications to delegate state storage to clients (in cookies, tokens, or URL query parameters) without risking payload tampering. It is designed around the following architectural guidelines: Zero Mandatory Dependencies: By default, all HMAC implementations use Python's standard library (e.g. hmac, hashlib). Namespace Isolation (Salting): Using salt values mixes namespaces into derived sub-keys, rendering signatures generated by different signers incompatible even when sharing the same master key. Constant-Time Comparisons: Signature validation utilizes hmac.compare_digest to protect against side-channel timing attacks. Algorithm Agility: Supports standard HMAC algorithms (HS256, HS384, HS512) and asymmetric signatures (RS256, ES256, EdDSA) via the optional cryptography package. Signing Faults & Exceptions Aquilia maps its standard faults to legacy exceptions, keeping client-code integration straightforward: class SigningError(SigningFault): """Base exception for all signing-related operations.""" class BadSignature(BadSignatureFault): """Raised when signature verification fails.""" class SignatureExpired(SignatureExpiredFault): """Raised when signature validation succeeds but timestamp age exceeds max_age.""" class SignatureMalformed(SignatureMalformedFault): """Raised when the token format or encoding is corrupted.""" class UnsupportedAlgorithmError(UnsupportedAlgorithmFault): """Raised when an algorithm is selected but its dependencies are missing.""" Low-Level Cryptographic Primitives The module exposes pure utility functions for URL-safe base64 encoding and sub-key derivation: def b64_encode(data: bytes) -> str: """URL-safe, no-padding Base64 encoder.""" def b64_decode(data: str | bytes) -> bytes: """URL-safe, no-padding Base64 decoder. Validates canonical encoding.""" def constant_time_compare(a: bytes | str, b: bytes | str) -> bool: """Compares strings in constant time to prevent timing attacks.""" def derive_key(secret: str | bytes, salt: str, algorithm: str = "HS256") -> bytes: """Derives a namespace-specific sub-key using HKDF-lite to prevent cross-confusion.""" Resource Management Core Signers )

### Code Examples
```python
class SigningError(SigningFault):
    """Base exception for all signing-related operations."""

class BadSignature(BadSignatureFault):
    """Raised when signature verification fails."""

class SignatureExpired(SignatureExpiredFault):
    """Raised when signature validation succeeds but timestamp age exceeds max_age."""

class SignatureMalformed(SignatureMalformedFault):
    """Raised when the token format or encoding is corrupted."""

class UnsupportedAlgorithmError(UnsupportedAlgorithmFault):
    """Raised when an algorithm is selected but its dependencies are missing."""
```

```python
def b64_encode(data: bytes) -> str:
    """URL-safe, no-padding Base64 encoder."""

def b64_decode(data: str | bytes) -> bytes:
    """URL-safe, no-padding Base64 decoder. Validates canonical encoding."""

def constant_time_compare(a: bytes | str, b: bytes | str) -> bool:
    """Compares strings in constant time to prevent timing attacks."""

def derive_key(secret: str | bytes, salt: str, algorithm: str = "HS256") -> bytes:
    """Derives a namespace-specific sub-key using HKDF-lite to prevent cross-confusion."""
```



---

## Core Signer Classes
**URL**: `https://tubox.cloud/docs/signing/signers`

SIGNING SYSTEM / CORE SIGNERS Core Signer Classes Discover the primary APIs for cryptographic signing: the stateless Signer class and the time-aware TimestampSigner. Signer API Reference The Signer class verifies simple string values. The output signature is appended as a Base64 block separated by a specified character (default :). class Signer: def __init__(self, secret: str | bytes | None = None, *, salt: str = "aquilia.signing", sep: str = ":", algorithm: str = "HS256", backend: SignerBackend | None = None) def sign(self, value: str) -> str: """Sign value and return ' : '.""" def unsign(self, signed_value: str) -> str: """Verify signature and return original value. Raises BadSignature on mismatch.""" def sign_bytes(self, data: bytes) -> bytes: """Sign binary blobs and return raw data + separator + signature.""" def unsign_bytes(self, signed_data: bytes) -> bytes: """Verify binary signature and return original bytes.""" def sign_object(self, obj: Any) -> str: """Serialise a JSON-compatible Python object, sign, and encode.""" def unsign_object(self, token: str) -> Any: """Verify signature and deserialise the JSON payload.""" TimestampSigner API Reference The TimestampSigner class embeds a UTC timestamp in microsecond precision (offset from 2020-01-01) inside the payload before signing. This enables enforcing token lifetimes at verification time. class TimestampSigner(Signer): def __init__(self, secret: str | bytes | None = None, *, salt: str = "aquilia.signing.ts", sep: str = ":", algorithm: str = "HS256", backend: SignerBackend | None = None) def sign(self, value: str, *, timestamp: datetime | None = None) -> str: """Sign value with an embedded timestamp.""" def unsign(self, signed_value: str, max_age: float | int | timedelta | None = None) -> str: """Verify signature and enforce age. Raises SignatureExpired if older than max_age.""" def unsign_with_timestamp(self, signed_value: str, max_age: float | int | timedelta | None = None) -> tuple[str, datetime]: """Verify signature and return tuple of (original_value, datetime_when_signed).""" Scenario Walkthroughs Scenario 1: Basic String Verification Verify stateless data elements passed in query parameters or custom HTTP headers: from aquilia.signing import Signer, BadSignature # 1. Initialize signer with a master key signer = Signer(secret="my-super-secret-key-32-bytes-minimum") # 2. Sign a username string signed_token = signer.sign("john_doe") print(signed_token) # e.g. "john_doe:aBcDeFgHiJ..." # 3. Verify signature on read try: username = signer.unsign(signed_token) except BadSignature: print("Tampered token detected!") Scenario 2: Binary Blob Integrity Maintain serialization integrity of binary objects, e.g. signed pickle payloads or encrypted files: import pickle from aquilia.signing import Signer signer = Signer(secret="my-super-secret-key-32-bytes-minimum") data = pickle_data = pickle.dumps(data) # Sign binary bytes signed_payload = signer.sign_bytes(pickle_data) # Unsign binary bytes and deserialize original_bytes = signer.unsign_bytes(signed_payload) restored_data = pickle.loads(original_bytes) Scenario 3: Expirable Tokens Enforce age validation on cryptographic signatures, automatically discarding tokens older than a set duration: import time from aquilia.signing import TimestampSigner, SignatureExpired, BadSignature ts = TimestampSigner(secret="my-super-secret-key-32-bytes-minimum") # Sign token (embeds current time) token = ts.sign("premium_user") # Sleep to simulate delay time.sleep(5) # Verify with max_age restriction (3 seconds) try: user = ts.unsign(token, max_age=3) except SignatureExpired as exc: print(f"Token expired! Signed at: ") except BadSignature: print("Invalid signature!") Overview Specialized Signers )

### Code Examples
```python
class Signer:
    def __init__(self, secret: str | bytes | None = None, *, salt: str = "aquilia.signing", sep: str = ":", algorithm: str = "HS256", backend: SignerBackend | None = None)
    
    def sign(self, value: str) -> str:
        """Sign value and return '<value>:<signature>'."""
        
    def unsign(self, signed_value: str) -> str:
        """Verify signature and return original value. Raises BadSignature on mismatch."""
        
    def sign_bytes(self, data: bytes) -> bytes:
        """Sign binary blobs and return raw data + separator + signature."""
        
    def unsign_bytes(self, signed_data: bytes) -> bytes:
        """Verify binary signature and return original bytes."""
        
    def sign_object(self, obj: Any) -> str:
        """Serialise a JSON-compatible Python object, sign, and encode."""
        
    def unsign_object(self, token: str) -> Any:
        """Verify signature and deserialise the JSON payload."""
```

```python
class TimestampSigner(Signer):
    def __init__(self, secret: str | bytes | None = None, *, salt: str = "aquilia.signing.ts", sep: str = ":", algorithm: str = "HS256", backend: SignerBackend | None = None)
    
    def sign(self, value: str, *, timestamp: datetime | None = None) -> str:
        """Sign value with an embedded timestamp."""
        
    def unsign(self, signed_value: str, max_age: float | int | timedelta | None = None) -> str:
        """Verify signature and enforce age. Raises SignatureExpired if older than max_age."""
        
    def unsign_with_timestamp(self, signed_value: str, max_age: float | int | timedelta | None = None) -> tuple[str, datetime]:
        """Verify signature and return tuple of (original_value, datetime_when_signed)."""
```

```python
from aquilia.signing import Signer, BadSignature

# 1. Initialize signer with a master key
signer = Signer(secret="my-super-secret-key-32-bytes-minimum")

# 2. Sign a username string
signed_token = signer.sign("john_doe")
print(signed_token)  # e.g. "john_doe:aBcDeFgHiJ..."

# 3. Verify signature on read
try:
    username = signer.unsign(signed_token)
except BadSignature:
    print("Tampered token detected!")
```



---

## Specialized Signers & Config
**URL**: `https://tubox.cloud/docs/signing/specialized`

SIGNING SYSTEM / SPECIALIZED SIGNERS Specialized Signers & Config Discover the subsystem-isolated signers and how to apply configurations globally at application startup. Subsystem-Specific Signers To prevent cross-subsystem token confusion (e.g. using a password reset token as a session cookie), Aquilia provides specialized classes with hardcoded namespace salts: class SessionSigner(TimestampSigner): # Salt: "aquilia.sessions". Used to secure session identifier cookies. class CSRFSigner(Signer): # Salt: "aquilia.csrf". Used to secure request CSRF tokens. Stateless. class ActivationLinkSigner(TimestampSigner): # Salt: "aquilia.activation". Enforces a default max_age of 24 hours. class CacheKeySigner(Signer): # Salt: "aquilia.cache". Used to sign cached bytes and prevent cache poisoning. class CookieSigner(TimestampSigner): # Salt: "aquilia.cookies". Used for user-space signed HTTP cookies. class APIKeySigner(TimestampSigner): # Salt: "aquilia.apikeys". Used to sign short-lived URL queries and access tokens. SigningConfig API Reference The SigningConfig dataclass defines configuration parameters mapped from the application config registry. @dataclass class SigningConfig: secret: str = "" fallback_secrets: list[str] = field(default_factory=list) algorithm: str = "HS256" salt: str = "aquilia.signing" session_salt: str = "aquilia.sessions" csrf_salt: str = "aquilia.csrf" activation_salt: str = "aquilia.activation" cache_salt: str = "aquilia.cache" def apply(self) -> None: """Configures the global secret registry.""" def make_session_signer(self) -> SessionSigner: ... def make_csrf_signer(self) -> CSRFSigner: ... def make_activation_signer(self) -> ActivationLinkSigner: ... def make_cache_signer(self) -> CacheKeySigner: ... def make_cookie_signer(self) -> CookieSigner: ... def make_api_key_signer(self) -> APIKeySigner: ... Scenario Walkthroughs Scenario 1: Applying Global Configurations Initialize signing configurations globally at application startup. This is typically invoked from your server entrypoint: from aquilia.signing import configure # 1. Load keys from environment variables or settings primary_secret = "master-secret-key-32-bytes-minimum" old_retired_key = "retired-key-32-bytes-minimum" # 2. Configure global signing registry configure( secret=primary_secret, fallback_secrets=[old_retired_key], algorithm="HS256" ) Scenario 2: Expirable Activation / Password Reset Links Generate signed password reset URLs. Verification enforces the default 24-hour limit: from aquilia.controller import Controller, GET, POST, RequestCtx from aquilia.signing import ActivationLinkSigner, SignatureExpired, BadSignature class ResetController(Controller): def initialize(self): self.signer = ActivationLinkSigner() @POST("/auth/reset-password/request") async def request_reset(self, ctx: RequestCtx): user_id = "user_984" # Generate token with activation-specific namespace token = self.signer.sign(user_id) reset_url = f"https://example.com/reset?token= " return @GET("/auth/reset-password/verify") async def verify_reset(self, ctx: RequestCtx): token = ctx.query.get("token", "") try: # Unsigns with default 24h max_age user_id = self.signer.unsign(token) return except SignatureExpired: return , 400 except BadSignature: return , 400 Core Signers Advanced Signing )

### Code Examples
```python
class SessionSigner(TimestampSigner):
    # Salt: "aquilia.sessions". Used to secure session identifier cookies.

class CSRFSigner(Signer):
    # Salt: "aquilia.csrf". Used to secure request CSRF tokens. Stateless.

class ActivationLinkSigner(TimestampSigner):
    # Salt: "aquilia.activation". Enforces a default max_age of 24 hours.

class CacheKeySigner(Signer):
    # Salt: "aquilia.cache". Used to sign cached bytes and prevent cache poisoning.

class CookieSigner(TimestampSigner):
    # Salt: "aquilia.cookies". Used for user-space signed HTTP cookies.

class APIKeySigner(TimestampSigner):
    # Salt: "aquilia.apikeys". Used to sign short-lived URL queries and access tokens.
```

```python
@dataclass
class SigningConfig:
    secret: str = ""
    fallback_secrets: list[str] = field(default_factory=list)
    algorithm: str = "HS256"
    salt: str = "aquilia.signing"
    session_salt: str = "aquilia.sessions"
    csrf_salt: str = "aquilia.csrf"
    activation_salt: str = "aquilia.activation"
    cache_salt: str = "aquilia.cache"
    
    def apply(self) -> None:
        """Configures the global secret registry."""
        
    def make_session_signer(self) -> SessionSigner: ...
    def make_csrf_signer(self) -> CSRFSigner: ...
    def make_activation_signer(self) -> ActivationLinkSigner: ...
    def make_cache_signer(self) -> CacheKeySigner: ...
    def make_cookie_signer(self) -> CookieSigner: ...
    def make_api_key_signer(self) -> APIKeySigner: ...
```

```python
from aquilia.signing import configure

# 1. Load keys from environment variables or settings
primary_secret = "master-secret-key-32-bytes-minimum"
old_retired_key = "retired-key-32-bytes-minimum"

# 2. Configure global signing registry
configure(
    secret=primary_secret,
    fallback_secrets=[old_retired_key],
    algorithm="HS256"
)
```



---

## Advanced Cryptographic Patterns
**URL**: `https://tubox.cloud/docs/signing/advanced`

SIGNING SYSTEM / ADVANCED SIGNING Advanced Cryptographic Patterns Discover transparent key rotation, compact zlib payload compression, and custom signer backends for asymmetric cryptography. Key Rotation When rotation keys in production, old tokens must remain valid until they naturally expire. The RotatingSigner class solves this: it always signs using the first secret key in the provided secrets array, but attempts verification against all configured keys in order. class RotatingSigner: def __init__(self, secrets: Sequence[str | bytes], *, salt: str = "aquilia.signing", sep: str = ":", algorithm: str = "HS256", timestamp: bool = False) def sign(self, value: str) -> str: """Signs using the current (first) secret key.""" def unsign(self, signed_value: str, max_age: float | int | timedelta | None = None) -> str: """Tries each secret in order. Returns verified value or raises BadSignature.""" Structured Serialization (Dumps & Loads) The dumps and loads helper functions serialize dictionaries and objects to URL-safe strings. If compress=True is set, the engine compresses the payload via zlib and adds a header byte (\x01) to indicate compression. def dumps(obj: Any, *, secret: str | bytes | None = None, salt: str = "aquilia.signing.dumps", algorithm: str = "HS256", compress: bool = False, max_age: float | int | timedelta | None = None, timestamp: bool = True) -> str: """Serialise a JSON-compatible object to a signed URL-safe string.""" def loads(token: str, *, secret: str | bytes | None = None, salt: str = "aquilia.signing.dumps", algorithm: str = "HS256", max_age: float | int | timedelta | None = None) -> Any: """Verify and deserialise a token back to its original object format.""" Custom Backends & Asymmetric Signing You can extend the signature generation mechanism by implementing the abstract SignerBackend base class. This enables integration with cloud KMS, hardware security modules (HSM), or asymmetric keys. Aquilia features a built-in AsymmetricSignerBackend that supports RS256, ES256, and EdDSA signatures (requires pip install cryptography). class SignerBackend(ABC): @abstractmethod def sign(self, message: bytes) -> bytes: ... @abstractmethod def verify(self, message: bytes, signature: bytes) -> bool: ... @property @abstractmethod def algorithm(self) -> str: ... class AsymmetricSignerBackend(SignerBackend): def __init__(self, algorithm: str, *, private_key_pem: str | None = None, public_key_pem: str | None = None) Scenario Walkthroughs Scenario 1: Zero-Downtime Key Rotation Retire old keys without logging users out or invalidating outstanding links: from aquilia.signing import RotatingSigner # secrets[0] = active key for new signatures # secrets[1:] = backup keys used for verifying old tokens keys = ["new_master_key_2026_32_bytes_min", "old_retired_key_2025_32_bytes_min"] signer = RotatingSigner(secrets=keys) # New signatures use the active key new_token = signer.sign("hello") # Verification succeeds on old tokens signed with the old key old_token = "hello:oldSignatureHexOrB64" value = signer.unsign(old_token) # returns "hello" Scenario 2: Signed Payload Serialization with Compression Serialize complex nested lists or dictionaries, compressing them with zlib to keep cookies or URLs compact: from aquilia.signing import dumps, loads session_data = # Serialize, compress payload, and generate signature token = dumps( session_data, secret="my-super-secret-key-32-bytes-minimum", compress=True ) # Decode, verify, and decompress payload data = loads( token, secret="my-super-secret-key-32-bytes-minimum", max_age=3600 ) Scenario 3: Asymmetric Signature Verification Utilize ES256 (ECDSA P-256) asymmetric signatures for verification, where the public key is distributed but private key is held securely on the auth server: from aquilia.signing import Signer, AsymmetricSignerBackend private_pem = """-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg... -----END PRIVATE KEY-----""" public_pem = """-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE... -----END PUBLIC KEY-----""" # 1. Create a backend with the ES256 algorithm backend = AsymmetricSignerBackend( algorithm="ES256", private_key_pem=private_pem, public_key_pem=public_pem ) # 2. Attach backend to the Signer signer = Signer(backend=backend) token = signer.sign("asymmetric_payload") Specialized Signers Fault System )

### Code Examples
```python
class RotatingSigner:
    def __init__(self, secrets: Sequence[str | bytes], *, salt: str = "aquilia.signing", sep: str = ":", algorithm: str = "HS256", timestamp: bool = False)
    
    def sign(self, value: str) -> str:
        """Signs using the current (first) secret key."""
        
    def unsign(self, signed_value: str, max_age: float | int | timedelta | None = None) -> str:
        """Tries each secret in order. Returns verified value or raises BadSignature."""
```

```python
def dumps(obj: Any, *, secret: str | bytes | None = None, salt: str = "aquilia.signing.dumps", algorithm: str = "HS256", compress: bool = False, max_age: float | int | timedelta | None = None, timestamp: bool = True) -> str:
    """Serialise a JSON-compatible object to a signed URL-safe string."""

def loads(token: str, *, secret: str | bytes | None = None, salt: str = "aquilia.signing.dumps", algorithm: str = "HS256", max_age: float | int | timedelta | None = None) -> Any:
    """Verify and deserialise a token back to its original object format."""
```

```python
class SignerBackend(ABC):
    @abstractmethod
    def sign(self, message: bytes) -> bytes: ...
    @abstractmethod
    def verify(self, message: bytes, signature: bytes) -> bool: ...
    @property
    @abstractmethod
    def algorithm(self) -> str: ...

class AsymmetricSignerBackend(SignerBackend):
    def __init__(self, algorithm: str, *, private_key_pem: str | None = None, public_key_pem: str | None = None)
```



---

## Structured Faults
**URL**: `https://tubox.cloud/docs/faults`

ADVANCED / FAULTS SYSTEM Structured Faults In Aquilia, errors are first-class structured values called Faults. Inheriting from Python's base Exception class, every Fault carries stable identifiers, classification domains, severity ratings, and recovery strategies. Why Structured Faults? Raw Python exceptions lack consistent structures, making it difficult for downstream HTTP middlewares or background workers to parse error details safely. A Fault encapsulates these properties: 1. ORIGIN Exception/Fault raised 2. ANNOTATION FaultContext wrapped 3. EMISSION Logs & listener dispatch 4. PROPAGATION Scope handler routing 5. RESOLUTION Resolved/Transformed result 6. RESPONSE Safe HTTP serialization Classification Domains Organizes errors by subsystem (e.g. CONFIG, DI, MODEL, CACHE), defining default severity and retry rules automatically. Public Exposure Controls The public boolean flag controls whether error messages can be returned directly to JSON clients or must be masked as 500 errors. Creating Faults from aquilia.faults import Fault, FaultDomain, Severity, RecoveryStrategy # Instantiating a structured fault raise Fault( code="USER_NOT_FOUND", message="Requested user ID does not exist", domain=FaultDomain.MODEL, severity=Severity.ERROR, public=True, retryable=False, user_id=123 # Arbitrary metadata fields are merged automatically ) Preserving Causality: Transform Chain Faults support the right shift operator >>. This allows handlers to catch lower-level errors (like database exceptions) and transform them into higher-level API faults while preserving causality: try: await db.execute("INSERT ...") except DatabaseError as err: # Transform lower-level database error to public API fault # Preserves the cause and updates the '_transform_chain' key in metadata raise DatabaseFault(code="DB_FAIL", message=str(err)) >> ApiFault("USER_CREATE_FAILED") Fault Taxonomy )

### Code Examples
```python
from aquilia.faults import Fault, FaultDomain, Severity, RecoveryStrategy

# Instantiating a structured fault
raise Fault(
    code="USER_NOT_FOUND",
    message="Requested user ID does not exist",
    domain=FaultDomain.MODEL,
    severity=Severity.ERROR,
    public=True,
    retryable=False,
    user_id=123 # Arbitrary metadata fields are merged automatically
)
```

```python
try:
    await db.execute("INSERT ...")
except DatabaseError as err:
    # Transform lower-level database error to public API fault
    # Preserves the cause and updates the '_transform_chain' key in metadata
    raise DatabaseFault(code="DB_FAIL", message=str(err)) >> ApiFault("USER_CREATE_FAILED")
```



---

## Fault Taxonomy & Outcomes
**URL**: `https://tubox.cloud/docs/faults/taxonomy`

FAULTS / TAXONOMY & RESULTS Fault Taxonomy & Outcomes Every error in Aquilia is categorized by its severity and domain, and processed by handlers returning a strict union type called FaultResult. Severity Classification The Severity enum dictates logging urgency and retry capabilities: Severity.INFO Informational incidents. Logged at info level, requires no immediate correction. Severity.WARN Degraded application behavior. Does not stop request execution. Severity.ERROR Request failed. Aborts the thread, requires handling or returns error response. Severity.FATAL System-level crash. Stops the process or aborts the entire ASGI lifespan. Handler outcomes: FaultResult A custom fault handler determines propagation by returning one of three frozen dataclasses that comprise the FaultResult type: Instructs the engine that the fault is handled. It stops propagation and returns the enclosed Response object directly. Transforms the active error into a new fault class and continues bubbling it up the handler chain. Declines handling the fault. It escalates the error to the next outer handler in the parent scope. from aquilia.faults import Resolved, Transformed, Escalate, FaultResult from aquilia.response import Response def handle_error(fault, ctx) -> FaultResult: if fault.code == "EXPIRED_SESSION": # Resolve error, return 401 response return Resolved(Response("Session expired", status=401)) if fault.code == "RAW_DB_ERROR": # Transform error return Transformed(ApiFault("DATABASE_ERROR")) # Otherwise escalate return Escalate() Overview FaultEngine )

### Code Examples
```python
from aquilia.faults import Resolved, Transformed, Escalate, FaultResult
from aquilia.response import Response

def handle_error(fault, ctx) -> FaultResult:
    if fault.code == "EXPIRED_SESSION":
        # Resolve error, return 401 response
        return Resolved(Response("Session expired", status=401))
        
    if fault.code == "RAW_DB_ERROR":
        # Transform error
        return Transformed(ApiFault("DATABASE_ERROR"))
        
    # Otherwise escalate
    return Escalate()
```



---

## FaultEngine Execution
**URL**: `https://tubox.cloud/docs/faults/engine`

FAULTS / FAULT ENGINE FaultEngine Execution The FaultEngine orchestrates runtime error resolution. It converts raw exceptions, coordinates scoped handlers, and enforces fallback policies. Engine Processing Stages When an uncaught exception is intercepted by the framework, FaultEngine executes four sequential stages: 1. Context Capture Wraps the exception inside a FaultContext object, capturing traceback frames, timestamp offsets, request identifiers, and trace IDs. 2. Scoped Handler Lookup Searches for matching handlers in a strict topological order: Route-specific handlers → App-specific handlers → Global handlers. 3. Execution Loop Runs candidate handlers in priority order. If a handler returns Resolved(response), execution halts and the response returns. If it returns Transformed(new_fault), the engine replaces the error and restarts the resolution loop. 4. ASGI Fallback If all handlers return Escalate() or decline (raising uncaught errors), the exception escapes to the ASGI FaultMiddleware, returning a masked 500 JSON response or rendering a debug traceback page. Wiring Handlers from aquilia.faults import FaultEngine engine = FaultEngine() # 1. Register a handler globally engine.register_global(CustomGlobalHandler()) # 2. Register an app-specific handler (app name must match manifest name) engine.register_app("auth", AuthModuleHandler()) Taxonomy Fault Handlers )

### Code Examples
```python
from aquilia.faults import FaultEngine

engine = FaultEngine()

# 1. Register a handler globally
engine.register_global(CustomGlobalHandler())

# 2. Register an app-specific handler (app name must match manifest name)
engine.register_app("auth", AuthModuleHandler())
```



---

## Fault Handlers
**URL**: `https://tubox.cloud/docs/faults/handlers`

FAULTS / FAULT HANDLERS Fault Handlers Custom handlers resolve propagating Faults. By implementing a two-method contract, handlers can intercept errors, translate them, or format custom responses. The FaultHandler Contract Every custom handler must inherit from FaultHandler and implement exactly two methods: Evaluates the FaultContext predicate. Returns True if this handler claims responsibility for the fault, allowing .handle() to run. Executes the resolution logic. Must return Resolved(response), Transformed(new_fault), or Escalate(). Writing a Custom Handler from aquilia.faults import FaultHandler, Resolved, Escalate, FaultResult from aquilia.response import Response class DatabaseConnectionFaultHandler(FaultHandler): """Custom handler for database outage faults.""" def can_handle(self, ctx) -> bool: # Match only DB-related faults with severe status return ctx.fault.domain.value == "model" and ctx.fault.code.startswith("DB_") async def handle(self, ctx) -> FaultResult: # Log active request variables print(f"Database error on: - ") if ctx.fault.retryable: # Let it escalate to a retry middleware return Escalate() # Return a structured JSON response return Resolved( Response( , status=503 ) ) FaultEngine Fault Domains )

### Code Examples
```python
from aquilia.faults import FaultHandler, Resolved, Escalate, FaultResult
from aquilia.response import Response

class DatabaseConnectionFaultHandler(FaultHandler):
    """Custom handler for database outage faults."""

    def can_handle(self, ctx) -> bool:
        # Match only DB-related faults with severe status
        return ctx.fault.domain.value == "model" and ctx.fault.code.startswith("DB_")

    async def handle(self, ctx) -> FaultResult:
        # Log active request variables
        print(f"Database error on: {ctx.request_id} - {ctx.fault.message}")
        
        if ctx.fault.retryable:
            # Let it escalate to a retry middleware
            return Escalate()
            
        # Return a structured JSON response
        return Resolved(
            Response(
                {"error": "Database temporarily unavailable", "code": "DB_OUTAGE"},
                status=503
            )
        )
```



---

## Fault Domains
**URL**: `https://tubox.cloud/docs/faults/domains`

FAULTS / FAULT DOMAINS Fault Domains Fault Domains group errors by their originating subsystem. Each domain has default settings for severity and retries, making it easier to define handling rules across entire subsystems. Built-in Subsystem Domains Fault Domain Default Severity Default Retryable Subsystem Description FaultDomain.CONFIG Severity.FATAL False Workspace or application configuration loading errors FaultDomain.REGISTRY Severity.FATAL False AppManifest loading or dependency cycle validation errors FaultDomain.DI Severity.ERROR False Dependency injection dependency resolution errors FaultDomain.ROUTING Severity.ERROR False URL matching and compiled routing layout conflicts FaultDomain.FLOW Severity.ERROR False Pipeline execution flow and context errors FaultDomain.EFFECT Severity.ERROR True Effect acquisition or provider release exceptions FaultDomain.IO Severity.WARN True Local I/O, file reading, or network stream interrupts FaultDomain.SECURITY Severity.ERROR False Auth guards, CSRF token validation, or CORS blocks FaultDomain.SYSTEM Severity.FATAL False Critical process constraints or machine environment errors FaultDomain.MODEL Severity.ERROR False ORM Model schema matching and database queries FaultDomain.CACHE Severity.ERROR True Cache namespace read/write or backend client timeouts FaultDomain.STORAGE Severity.ERROR False Object storage bucket sync or driver exceptions FaultDomain.TASKS Severity.ERROR True Background task engine worker thread failures FaultDomain.TEMPLATE Severity.ERROR False HTML template compile or sandboxed rendering context errors FaultDomain.HTTP Severity.WARN False Outbound client HTTP request failures Fault Handlers Advanced Handlers )


---

## Custom Domains & Debugging
**URL**: `https://tubox.cloud/docs/faults/advanced`

FAULTS / ADVANCED TOPICS Custom Domains & Debugging Configure custom domains to group application-specific errors, and customize the HTML debug pages shown during local development. Custom Domains By default, Aquilia includes domains like FaultDomain.MODEL or FaultDomain.SECURITY. To define your own application-specific domain, use the FaultDomain.custom(name, description) factory method: from aquilia.faults import FaultDomain, Fault # 1. Instantiate custom domain BILLING_DOMAIN = FaultDomain.custom("billing", "Errors originating from the Stripe payment flows") # 2. Use the domain in a Fault instantiation raise Fault( code="PAYMENT_FAILED", message="Credit card transaction was declined by Stripe", domain=BILLING_DOMAIN, public=True, ) Development Debug Pages When running in local development mode (debug=True), unhandled Exceptions or Faults originating from HTML clients (Accept: text/html) render beautiful, interactive diagnostics: - Source Code View: Shows syntax-highlighted source code slices surrounding the line that raised the error. - Local Variables: Dumps variable values for every traceback stack frame. - Request Inspection: Displays raw ASGI scopes, headers, active cookies, and body sizes. from aquilia.debug import DebugPageRenderer # The ExceptionMiddleware instantiates the renderer automatically: renderer = DebugPageRenderer( show_locals=True, # Dump local variables in stack frames context_lines=7 # Number of surrounding lines of source code to display ) Fault Domains Cache )

### Code Examples
```python
from aquilia.faults import FaultDomain, Fault

# 1. Instantiate custom domain
BILLING_DOMAIN = FaultDomain.custom("billing", "Errors originating from the Stripe payment flows")

# 2. Use the domain in a Fault instantiation
raise Fault(
    code="PAYMENT_FAILED",
    message="Credit card transaction was declined by Stripe",
    domain=BILLING_DOMAIN,
    public=True,
)
```

```python
from aquilia.debug import DebugPageRenderer

# The ExceptionMiddleware instantiates the renderer automatically:
renderer = DebugPageRenderer(
    show_locals=True,      # Dump local variables in stack frames
    context_lines=7        # Number of surrounding lines of source code to display
)
```



---

## AquilaCache Overview
**URL**: `https://tubox.cloud/docs/cache`

Advanced / Cache AquilaCache Overview AquilaCache is Aquilia&apos;s async-native cache subsystem. It provides a DI-injectable CacheService , pluggable backends (Memory, Redis, Composite L1/L2), HTTP response-caching middleware, decorators, and tag-based invalidation. Runtime Wiring The cache system initializes early in the server bootstrap lifecycle inside _setup_cache(), registers providers into all active DI containers, and binds lifecycle startup/shutdown handlers. # 1. Load configuration via ConfigLoader cache_config = self.config.get_cache_config() if not cache_config.get("enabled", False): return # 2. Build configuration model and instantiate service config_obj = build_cache_config(cache_config) svc = create_cache_service(config_obj) # 3. Register service inside all active DI containers for container in self.runtime.di_containers.values(): register_cache_providers(container, svc) self._cache_service = svc # 4. Conditionally add HTTP response-cache middleware mw_cfg = cache_config.get("middleware", ) if mw_cfg.get("enabled", False): self.middleware_stack.add( CacheMiddleware(cache_service=svc, ttl=mw_cfg.get("ttl", 300)), scope="global", priority=26, name="cache", ) Workspace-Level Integration At the workspace level, you declare cache configurations globally in your workspace.py. This configures the default backend, serialization, default TTL, and middleware behaviors. from aquilia import Workspace from aquilia.integrations import CacheIntegration workspace = ( Workspace("product-service") .integrate(CacheIntegration( backend="composite", # L1 Memory + L2 Redis composite backend default_ttl=300, serializer="json", redis_url="redis://localhost:6379/0", middleware_enabled=True, # Activates CacheMiddleware middleware_default_ttl=60, )) ) Manifest-Level & Controller Integration Modules declare services and controllers in their AppManifest. Because the cache service is pre-registered in the DI container, components can request CacheService via constructor dependency injection automatically. from aquilia import AppManifest from .controllers import ProductController from .services import ProductService manifest = AppManifest( name="catalog", services=[ProductService], controllers=[ProductController], ) from aquilia import Controller, GET, RequestCtx from aquilia.cache import CacheService class ProductController(Controller): prefix = "/products" # Dependency Injection resolves CacheService automatically def __init__(self, cache: CacheService): self.cache = cache @GET("/ ") async def get_product(self, ctx: RequestCtx): product_id = ctx.path_params["product_id"] # Load from cache, or invoke database loader on miss return await self.cache.get_or_set( key=f"product: ", loader=lambda: self.db_fetch(product_id), ttl=120, tags=("products", f"product: ") ) Current Behavior Notes ))} Dive Deeper , , , , , , ].map((item) => ( ))} )

### Code Examples
```python
# 1. Load configuration via ConfigLoader
cache_config = self.config.get_cache_config()
if not cache_config.get("enabled", False):
    return

# 2. Build configuration model and instantiate service
config_obj = build_cache_config(cache_config)
svc = create_cache_service(config_obj)

# 3. Register service inside all active DI containers
for container in self.runtime.di_containers.values():
    register_cache_providers(container, svc)

self._cache_service = svc

# 4. Conditionally add HTTP response-cache middleware
mw_cfg = cache_config.get("middleware", {})
if mw_cfg.get("enabled", False):
    self.middleware_stack.add(
        CacheMiddleware(cache_service=svc, ttl=mw_cfg.get("ttl", 300)),
        scope="global",
        priority=26,
        name="cache",
    )
```

```python
from aquilia import Workspace
from aquilia.integrations import CacheIntegration

workspace = (
    Workspace("product-service")
    .integrate(CacheIntegration(
        backend="composite",         # L1 Memory + L2 Redis composite backend
        default_ttl=300,
        serializer="json",
        redis_url="redis://localhost:6379/0",
        middleware_enabled=True,     # Activates CacheMiddleware
        middleware_default_ttl=60,
    ))
)
```

```python
from aquilia import AppManifest
from .controllers import ProductController
from .services import ProductService

manifest = AppManifest(
    name="catalog",
    services=[ProductService],
    controllers=[ProductController],
)
```



---

## Cache Configuration
**URL**: `https://tubox.cloud/docs/cache/configuration`

Cache / Configuration Cache Configuration Configure AquilaCache via workspace integrations, typed integration dataclasses, Python-native config classes, and AQ_* environment overlays. Primary Configuration Paths from aquilia import Workspace, Integration from aquilia.integrations import CacheIntegration workspace = ( Workspace("myapp") # Dict-based API .integrate(Integration.cache( backend="redis", redis_url="redis://localhost:6379/0", default_ttl=300, serializer="json", middleware_enabled=True, middleware_default_ttl=60, )) # Typed Integration API .integrate(CacheIntegration( backend="memory", default_ttl=120, max_size=10000, eviction_policy="lru", )) ) AquilaConfig.Cache (Python-native) from aquilia.config_builders import AquilaConfig, Env class BaseEnv(AquilaConfig): class Cache(AquilaConfig.Cache): backend = Env("AQ_CACHE_BACKEND", default="memory") default_ttl = 300 max_size = 10000 eviction_policy = "lru" namespace = "default" key_prefix = "aq:" redis_url = Env("AQ_CACHE_REDIS_URL", default="redis://localhost:6379/0") Environment Mapping ConfigLoader ingests AQ_ prefixed variables and maps nested paths using double underscores: # Flat key AQ_CACHE__BACKEND=redis AQ_CACHE__DEFAULT_TTL=600 AQ_CACHE__REDIS_URL=redis://cache:6379/0 # Response cache middleware settings AQ_CACHE__MIDDLEWARE_ENABLED=true AQ_CACHE__MIDDLEWARE_DEFAULT_TTL=45 AQ_CACHE__MIDDLEWARE_STALE_WHILE_REVALIDATE=30 Configuration Precedence: environment variables have higher priority than defaults declared in Python configuration files, allowing seamless deployment adjustments. Field Reference Key Type Description ))} How Config Is Loaded from aquilia.config import ConfigLoader loader = ConfigLoader.load() cache_cfg = loader.get_cache_config() # get_cache_config() behavior: # 1) starts from built-in defaults # 2) overlays root "cache" if present # 3) falls back to "integrations.cache" if root cache is missing # 4) forces enabled=True when user cache config exists Current Behavior Notes • Cache config keys are flat (e.g. middleware_enabled), whereas the ASGI server auto-wiring routine checks nested cache.middleware dict properties when enabling CacheMiddleware . • The HMAC-signed PickleCacheSerializer requires a secret_key to decrypt payloads. Ensure this is passed during custom instantiation since the automated loader doesn't fetch it dynamically. )

### Code Examples
```python
from aquilia import Workspace, Integration
from aquilia.integrations import CacheIntegration

workspace = (
    Workspace("myapp")
    # Dict-based API
    .integrate(Integration.cache(
        backend="redis",
        redis_url="redis://localhost:6379/0",
        default_ttl=300,
        serializer="json",
        middleware_enabled=True,
        middleware_default_ttl=60,
    ))

    # Typed Integration API
    .integrate(CacheIntegration(
        backend="memory",
        default_ttl=120,
        max_size=10000,
        eviction_policy="lru",
    ))
)
```

```python
from aquilia.config_builders import AquilaConfig, Env

class BaseEnv(AquilaConfig):
    class Cache(AquilaConfig.Cache):
        backend = Env("AQ_CACHE_BACKEND", default="memory")
        default_ttl = 300
        max_size = 10000
        eviction_policy = "lru"
        namespace = "default"
        key_prefix = "aq:"
        redis_url = Env("AQ_CACHE_REDIS_URL", default="redis://localhost:6379/0")
```

```python
# Flat key
AQ_CACHE__BACKEND=redis
AQ_CACHE__DEFAULT_TTL=600
AQ_CACHE__REDIS_URL=redis://cache:6379/0

# Response cache middleware settings
AQ_CACHE__MIDDLEWARE_ENABLED=true
AQ_CACHE__MIDDLEWARE_DEFAULT_TTL=45
AQ_CACHE__MIDDLEWARE_STALE_WHILE_REVALIDATE=30
```



---

## Cache CLI
**URL**: `https://tubox.cloud/docs/cache/cli`

Cache / CLI Cache CLI Aquilia exposes cache management via the aq cache command group. Commands are registered in aquilia/cli/__main__.py and implemented in aquilia/cli/commands/cache.py. Command Surface Command Description ))} aq cache check Loads cache config and prints key settings (backend, TTL, serializer, key prefix, and backend-specific details). For the Redis backend, it attempts a synchronous ping query to verify network connectivity. aq cache check aq cache check -v aq cache inspect Outputs cache configuration as JSON. It first attempts to load from the workspace module and falls back to ConfigLoader defaults. aq cache inspect aq cache inspect -v aq cache stats Builds a temporary CacheService and initializes it, then attempts to retrieve and display statistics from the active cache backend. aq cache stats aq cache stats -v Warning: The stats command expects the backend cache service to expose an info() call. Because CacheService uses stats(), this command output may be empty for some backends. aq cache clear Creates a temporary CacheService from config, initializes it, clears all entries or a single namespace, then shuts down the temporary service. # Clear all keys aq cache clear # Clear one namespace aq cache clear --namespace http Config Loading Logic def _load_cache_config() -> dict: # 1) workspace.py -> workspace.to_dict() -> cache or integrations.cache # 2) fallback ConfigLoader().get_cache_config() Operational Caveats • The check command expects nested config structures in the validation output paths, while standard cache configuration variables are flat. • CLI commands run in their own ephemeral process context. They do not hook into or share the in-memory cache allocations of separate running application server instances. )

### Code Examples
```python
aq cache check
aq cache check -v
```

```python
aq cache inspect
aq cache inspect -v
```

```python
aq cache stats
aq cache stats -v
```



---

## CacheService
**URL**: `https://tubox.cloud/docs/cache/service`

Cache / CacheService CacheService CacheService is the primary app-facing API. It wraps a CacheBackend with namespacing, key prefixing, TTL jitter, stampede prevention, and structured fault emission. Constructor and Properties from aquilia.cache import CacheService, CacheConfig service = CacheService( backend=my_backend, config=CacheConfig(default_ttl=300, namespace="default"), ) # Properties service.backend # Returns the CacheBackend service.config # Returns the CacheConfig service.is_distributed # bool (delegates to backend) service.is_healthy # bool (checks initialized + health state) Method Reference Signature Behavior ))} Cache-Aside and Stampede Prevention The get_or_set(...) pattern supports thundering-herd stampede prevention using a process-local in-memory singleflight futures map. While a key is being fetched, concurrent duplicate reads wait on the primary loader: from aquilia.cache import CacheService class UserService: def __init__(self, cache: CacheService, repo): self.cache = cache self.repo = repo async def get_user(self, user_id: str): return await self.cache.get_or_set( key=f"user: ", loader=lambda: self.repo.find_user(user_id), ttl=300, namespace="users", tags=("users", f"user: "), ) Batch and Invalidation Operations from aquilia.cache import CacheService async def refresh_catalog(cache: CacheService, catalog_items: dict[str, dict]): await cache.set_many( items= ": v for k, v in catalog_items.items()}, ttl=120, namespace="catalog", ) values = await cache.get_many(["product:1", "product:2"], namespace="catalog") # Invalidate by tags (group invalidation) await cache.invalidate_tags("products") # Invalidate whole namespace await cache.invalidate_namespace("catalog") return values Observability and Health stats = await cache.stats() print(stats.to_dict()) ok = await cache.health_check() print("cache healthy:", ok) Behavior Notes • get(...) and get_many(...) degrade gracefully, returning default values on connection errors rather than raising exceptions. • set(...) and set_many(...) log errors and emit a structured cache fault, but do not raise, ensuring data persistence errors do not block the request. • Stampede prevention is local to the current python worker process. Coalescence does not occur across separate host nodes or parallel server processes. DI Example Inject CacheService directly into controllers through dependency injection: from aquilia import Controller, GET from aquilia.cache import CacheService class ProductController(Controller): prefix = "/products" def __init__(self, cache: CacheService): self.cache = cache @GET("/ ") async def get_product(self, ctx, id: int): product = await self.cache.get_or_set( f"product: ", lambda: self.repo.find(id), ttl=300, namespace="catalog", ) return product )

### Code Examples
```python
from aquilia.cache import CacheService, CacheConfig

service = CacheService(
    backend=my_backend,
    config=CacheConfig(default_ttl=300, namespace="default"),
)

# Properties
service.backend         # Returns the CacheBackend
service.config          # Returns the CacheConfig
service.is_distributed  # bool (delegates to backend)
service.is_healthy      # bool (checks initialized + health state)
```

```python
from aquilia.cache import CacheService

class UserService:
    def __init__(self, cache: CacheService, repo):
        self.cache = cache
        self.repo = repo

    async def get_user(self, user_id: str):
        return await self.cache.get_or_set(
            key=f"user:{user_id}",
            loader=lambda: self.repo.find_user(user_id),
            ttl=300,
            namespace="users",
            tags=("users", f"user:{user_id}"),
        )
```

```python
from aquilia.cache import CacheService

async def refresh_catalog(cache: CacheService, catalog_items: dict[str, dict]):
    await cache.set_many(
        items={f"product:{k}": v for k, v in catalog_items.items()},
        ttl=120,
        namespace="catalog",
    )

    values = await cache.get_many(["product:1", "product:2"], namespace="catalog")

    # Invalidate by tags (group invalidation)
    await cache.invalidate_tags("products")

    # Invalidate whole namespace
    await cache.invalidate_namespace("catalog")

    return values
```



---

## Cache Backends
**URL**: `https://tubox.cloud/docs/cache/backends`

Cache / Backends Cache Backends Aquilia ships with four built-in cache backends conforming to the CacheBackend interface. All can be transparently swapped behind the same CacheService instance. Backend Comparison Backend Persistence Distributed Primary Strength Best For ))} CacheBackend Contract class CacheBackend(ABC): async def initialize(self) -> None: ... async def shutdown(self) -> None: ... async def get(self, key: str) -> CacheEntry | None: ... async def set(self, key: str, value: Any, ttl: int | None = None, tags: tuple[str, ...] = (), namespace: str = "default") -> None: ... async def delete(self, key: str) -> bool: ... async def exists(self, key: str) -> bool: ... async def clear(self, namespace: str | None = None) -> int: ... async def keys(self, pattern: str = "*", namespace: str | None = None) -> list[str]: ... async def stats(self) -> CacheStats: ... # Optional methods with defaults in base class: async def delete_by_tags(self, tags: set[str]) -> int: ... async def get_many(self, keys: list[str]) -> dict[str, CacheEntry | None]: ... async def set_many(self, items: dict[str, Any], ttl: int | None = None, namespace: str = "default") -> None: ... async def delete_many(self, keys: list[str]) -> int: ... async def increment(self, key: str, delta: int = 1) -> int | None: ... async def decrement(self, key: str, delta: int = 1) -> int | None: ... @property def name(self) -> str: ... @property def is_distributed(self) -> bool: ... MemoryBackend In-process cache utilizing locks for concurrency control, an asynchronous sweeper task for TTL management, inverted indexes for tag-based groupings, and configurable eviction policies (lru, lfu, fifo, ttl, random). from aquilia.cache import MemoryBackend, CacheService backend = MemoryBackend( max_size=10_000, eviction_policy="lru", sweep_interval=30.0, max_memory_bytes=0, capacity_warning_threshold=0.85, ) cache = CacheService(backend=backend) await cache.initialize() • Stores detailed metadata for each entry, including creation times, access frequencies, namespaces, and sizes. • The active background sweeper runs periodically to evict expired items from a sorted TTL min-heap. RedisBackend A distributed caching backend communicating with Redis databases. Manages connection pooling, pipelined batch transactions, and uses Redis Sets for O(1) tag and namespace lookups. from aquilia.cache import RedisBackend, CacheService backend = RedisBackend( url="redis://localhost:6379/0", max_connections=20, key_prefix="aq:", socket_timeout=5.0, connect_timeout=5.0, retry_on_timeout=True, ) cache = CacheService(backend=backend) await cache.initialize() • Uses namespaces and key prefix mapping. Tags are stored in Redis Sets named _tags: . • Pluggable serialization supports JSON, Msgpack, and Pickle options. CompositeBackend (L1/L2) Combines a fast local L1 memory cache and a distributed L2 Redis cache. Reads hit L1 first, falling back to L2. Found L2 values are promoted to L1, and writes update both levels simultaneously. from aquilia.cache import ( CompositeBackend, MemoryBackend, RedisBackend, CacheService, ) l1 = MemoryBackend(max_size=1_000) l2 = RedisBackend(url="redis://localhost:6379/0") backend = CompositeBackend( l1=l1, l2=l2, promote_on_l2_hit=True, async_l2_write=False, ) cache = CacheService(backend=backend) NullBackend No-op cache backend implementation. Always misses reads and ignores write operations. Useful for testing or disabling cache systems in production without changing application code. from aquilia.cache import NullBackend, CacheService cache = CacheService(backend=NullBackend()) Cache Serializers Serialization formats are crucial for L2/Redis backends. Three serializers are supported: JsonCacheSerializer Default option. Converts values into JSON bytes. Highly portable and secure, but limited to JSON-compatible data types. MsgpackCacheSerializer High-speed, compact binary representation. Requires the optional msgpack package. PickleCacheSerializer Standard Python pickle serialization. Supports arbitrary Python objects. Encrypted/signed using an HMAC signature via secret_key to prevent tampering. from aquilia.cache.serializers import get_serializer json_ser = get_serializer("json") msgpack_ser = get_serializer("msgpack") pickle_ser = get_serializer("pickle", secret_key="secure-hmac-key") Key Builders Key builders normalize logical keys into unique string descriptors. from aquilia.cache import DefaultKeyBuilder, HashKeyBuilder default_builder = DefaultKeyBuilder(version=1) print(default_builder.build(namespace="users", key="42", prefix="aq:")) # Output: aq:v1:users:42 hash_builder = HashKeyBuilder(hash_length=16, version=1) print(hash_builder.build(namespace="search", key="long-query", prefix="aq:")) # Output: aq:v1:search: )

### Code Examples
```python
class CacheBackend(ABC):
    async def initialize(self) -> None: ...
    async def shutdown(self) -> None: ...
    async def get(self, key: str) -> CacheEntry | None: ...
    async def set(self, key: str, value: Any, ttl: int | None = None, tags: tuple[str, ...] = (), namespace: str = "default") -> None: ...
    async def delete(self, key: str) -> bool: ...
    async def exists(self, key: str) -> bool: ...
    async def clear(self, namespace: str | None = None) -> int: ...
    async def keys(self, pattern: str = "*", namespace: str | None = None) -> list[str]: ...
    async def stats(self) -> CacheStats: ...

    # Optional methods with defaults in base class:
    async def delete_by_tags(self, tags: set[str]) -> int: ...
    async def get_many(self, keys: list[str]) -> dict[str, CacheEntry | None]: ...
    async def set_many(self, items: dict[str, Any], ttl: int | None = None, namespace: str = "default") -> None: ...
    async def delete_many(self, keys: list[str]) -> int: ...
    async def increment(self, key: str, delta: int = 1) -> int | None: ...
    async def decrement(self, key: str, delta: int = 1) -> int | None: ...

    @property
    def name(self) -> str: ...

    @property
    def is_distributed(self) -> bool: ...
```

```python
from aquilia.cache import MemoryBackend, CacheService

backend = MemoryBackend(
    max_size=10_000,
    eviction_policy="lru",
    sweep_interval=30.0,
    max_memory_bytes=0,
    capacity_warning_threshold=0.85,
)

cache = CacheService(backend=backend)
await cache.initialize()
```

```python
from aquilia.cache import RedisBackend, CacheService

backend = RedisBackend(
    url="redis://localhost:6379/0",
    max_connections=20,
    key_prefix="aq:",
    socket_timeout=5.0,
    connect_timeout=5.0,
    retry_on_timeout=True,
)

cache = CacheService(backend=backend)
await cache.initialize()
```



---

## Cache Decorators
**URL**: `https://tubox.cloud/docs/cache/decorators`

Cache / Decorators Cache Decorators AquilaCache includes function decorators for declarative read caching and invalidation, plus an HTTP response-cache middleware. @cached Caches function results by key. On a cache miss, it executes the target function, optionally validates the result, and stores it in the cache with the specified TTL and tags. @cached( ttl: int = 300, namespace: str = "default", key: str | None = None, key_func: Callable[..., str] | None = None, # (func, args, kwargs) -> key tags: tuple[str, ...] = (), unless: Callable[..., bool] | None = None, # skip caching if True condition: Callable[[Any], bool] | None = None, # cache only if True ) from aquilia.cache import cached @cached(ttl=60, namespace="api") async def get_popular_products(): return await db.fetch_all("SELECT * FROM products ORDER BY views DESC LIMIT 20") @cached( ttl=300, key_func=lambda func, args, kwargs: f"user: ", condition=lambda result: result is not None, ) async def get_user_profile(user_id: int): return await User.objects.get(id=user_id) @cached( ttl=120, namespace="feed", unless=lambda *args, **kwargs: kwargs.get("no_cache", False), ) async def get_feed(user_id: str, *, no_cache: bool = False): return await feed_repo.fetch(user_id) @cache_aside A semantic alias for @cached with identical runtime behavior. Use it to indicate that the decorated function is the authoritative source of truth for the cached data. from aquilia.cache import cache_aside @cache_aside(ttl=180, namespace="products", tags=("products",)) async def find_product(product_id: int): return await Product.objects.get(id=product_id) @invalidate Executes the wrapped function first (typically a write operation), and then invalidates specified keys and/or tags. @invalidate( *keys: str, namespace: str = "default", tags: tuple[str, ...] = (), ) from aquilia.cache import invalidate @invalidate("products:list:v1", namespace="catalog", tags=("products",)) async def create_product(data: dict): return await product_repo.create(data) @invalidate(tags=("products", "catalog:list"), namespace="catalog") async def import_products(batch: list[dict]): return await product_repo.bulk_insert(batch) CacheMiddleware HTTP response cache middleware. Intercepts incoming requests, generates and validates ETags, vary headers, and serves cached response payloads for GET/HEAD methods. CacheMiddleware( cache_service, default_ttl: int = 60, cacheable_methods: tuple[str, ...] = ("GET", "HEAD"), vary_headers: tuple[str, ...] = ("Accept", "Accept-Encoding"), namespace: str = "http_response", stale_while_revalidate: int = 0, ) from aquilia.cache.middleware import CacheMiddleware server.middleware_stack.add( CacheMiddleware( cache_service=cache_service, default_ttl=60, cacheable_methods=("GET", "HEAD"), vary_headers=("Accept", "Accept-Encoding", "Authorization"), namespace="http", stale_while_revalidate=30, ), scope="global", priority=26, name="cache", ) Decorator Cache Resolution Decorators automatically resolve the active CacheService in the following order: Checks for a self.cache attribute on the first argument (typical for controllers). Checks for a self._cache attribute on the first argument. Falls back to the module-level default cache service registered via set_default_cache_service(...). from aquilia.cache.decorators import set_default_cache_service # Optional manual setup if using decorators on standalone helper functions set_default_cache_service(cache_service) )

### Code Examples
```python
@cached(
    ttl: int = 300,
    namespace: str = "default",
    key: str | None = None,
    key_func: Callable[..., str] | None = None,   # (func, args, kwargs) -> key
    tags: tuple[str, ...] = (),
    unless: Callable[..., bool] | None = None,    # skip caching if True
    condition: Callable[[Any], bool] | None = None, # cache only if True
)
```

```python
from aquilia.cache import cached

@cached(ttl=60, namespace="api")
async def get_popular_products():
    return await db.fetch_all("SELECT * FROM products ORDER BY views DESC LIMIT 20")

@cached(
    ttl=300,
    key_func=lambda func, args, kwargs: f"user:{kwargs.get('user_id', args[0])}",
    condition=lambda result: result is not None,
)
async def get_user_profile(user_id: int):
    return await User.objects.get(id=user_id)

@cached(
    ttl=120,
    namespace="feed",
    unless=lambda *args, **kwargs: kwargs.get("no_cache", False),
)
async def get_feed(user_id: str, *, no_cache: bool = False):
    return await feed_repo.fetch(user_id)
```

```python
from aquilia.cache import cache_aside

@cache_aside(ttl=180, namespace="products", tags=("products",))
async def find_product(product_id: int):
    return await Product.objects.get(id=product_id)
```



---

## Cache API Reference
**URL**: `https://tubox.cloud/docs/cache/api-reference`

Cache / API Reference Cache API Reference Complete public symbol map for aquilia.cache and related DI and serializer helpers. Module Export Surface from aquilia.cache import ( # Core CacheBackend, CacheEntry, CacheStats, CacheConfig, CacheSerializer, CacheKeyBuilder, EvictionPolicy, # Backends MemoryBackend, RedisBackend, CompositeBackend, NullBackend, # Service and middleware CacheService, CacheMiddleware, # Decorators cached, cache_aside, invalidate, set_default_cache_service, get_default_cache_service, # Key builders DefaultKeyBuilder, HashKeyBuilder, # Serializers JsonCacheSerializer, MsgpackCacheSerializer, PickleCacheSerializer, # Faults CacheFault, CacheMissFault, CacheConnectionFault, CacheSerializationFault, CacheCapacityFault, CacheBackendFault, CacheConfigFault, CacheStampedeFault, CacheHealthFault, ) Core Types Symbol Description ))} Public Classes Class Description ))} Decorator Functions Function Description ))} Fault Types Fault Description ))} DI Provider Helpers from aquilia.cache.di_providers import ( build_cache_config, create_cache_backend, create_cache_service, register_cache_providers, ) cache_config = build_cache_config(raw_config_dict) cache_service = create_cache_service(cache_config) register_cache_providers(container, cache_service) • register_cache_providers adds CacheService and CacheBackend definitions to the application container scope. • Serialization configurations resolve active serializer mappings via get_serializer(name). )

### Code Examples
```python
from aquilia.cache import (
    # Core
    CacheBackend, CacheEntry, CacheStats, CacheConfig, CacheSerializer,
    CacheKeyBuilder, EvictionPolicy,

    # Backends
    MemoryBackend, RedisBackend, CompositeBackend, NullBackend,

    # Service and middleware
    CacheService, CacheMiddleware,

    # Decorators
    cached, cache_aside, invalidate,
    set_default_cache_service, get_default_cache_service,

    # Key builders
    DefaultKeyBuilder, HashKeyBuilder,

    # Serializers
    JsonCacheSerializer, MsgpackCacheSerializer, PickleCacheSerializer,

    # Faults
    CacheFault, CacheMissFault, CacheConnectionFault,
    CacheSerializationFault, CacheCapacityFault, CacheBackendFault,
    CacheConfigFault, CacheStampedeFault, CacheHealthFault,
)
```

```python
from aquilia.cache.di_providers import (
    build_cache_config,
    create_cache_backend,
    create_cache_service,
    register_cache_providers,
)

cache_config = build_cache_config(raw_config_dict)
cache_service = create_cache_service(cache_config)
register_cache_providers(container, cache_service)
```



---

## HTTP Client
**URL**: `https://tubox.cloud/docs/http`

HTTP Client HTTP Client A fully asynchronous, production-grade HTTP client built natively into Aquilia. Zero external dependencies, deep framework integration, and designed for high-performance async workloads. Design Philosophy Aquilia&apos;s HTTP client is not a wrapper around existing libraries—it is a native implementation using Python&apos;s asyncio primitives, providing: , , , , ].map((item, i) => ( ))} Quick Example from aquilia import Controller, GET from aquilia.http import AsyncHTTPClient, HTTPClientConfig from aquilia.http.config import TimeoutConfig class WeatherController(Controller): prefix = "/weather" def __init__(self): self.http = AsyncHTTPClient(HTTPClientConfig( timeout=TimeoutConfig(total=5.0), user_agent="Aquilia/1.0", )) @GET("/ ") async def get_weather(self, ctx, city: str): # Make HTTP request response = await self.http.get( f"https://api.weather.com/v1/current/ ", headers= , ) # Parse JSON response data = await response.json() return ctx.json(data) async def __aenter__(self): return self async def __aexit__(self, *exc): await self.http.close() Core Features , , , , , , , , , , ].map((item, i) => ( ))} Architecture The HTTP client layers separate high-level APIs from low-level TCP/TLS transport protocols: AsyncHTTPClient Entry point API providing HTTP verb methods (get(), post(), etc.) wrapping the active session. HTTPSession Manages stateful cookies, headers, redirect limits, and executes the active middleware and interceptor chains. RequestBuilder Fluid API to validate headers, encode parameters, and serialize body contents. NativeTransport Handles async SSL/TCP socket connections, serializes HTTP headers, and parses responses in chunks. Dive Deeper , , , , , , ].map((item) => ( ))} Templates HTTPClient Basics )

### Code Examples
```python
from aquilia import Controller, GET
from aquilia.http import AsyncHTTPClient, HTTPClientConfig
from aquilia.http.config import TimeoutConfig

class WeatherController(Controller):
    prefix = "/weather"
    
    def __init__(self):
        self.http = AsyncHTTPClient(HTTPClientConfig(
            timeout=TimeoutConfig(total=5.0),
            user_agent="Aquilia/1.0",
        ))
    
    @GET("/{city}")
    async def get_weather(self, ctx, city: str):
        # Make HTTP request
        response = await self.http.get(
            f"https://api.weather.com/v1/current/{city}",
            headers={"API-Key": "your-key"},
        )
        
        # Parse JSON response
        data = await response.json()
        return ctx.json(data)
    
    async def __aenter__(self):
        return self
    
    async def __aexit__(self, *exc):
        await self.http.close()
```



---

## HTTPClient
**URL**: `https://tubox.cloud/docs/http/client`

HTTP Client / Basics HTTPClient The AsyncHTTPClient class provides a high-level async API for making HTTP requests with built-in retry logic, interceptors, and connection pooling. Basic Usage from aquilia.http import AsyncHTTPClient async def main(): # Create client client = AsyncHTTPClient() try: # Make GET request response = await client.get("https://api.github.com/users/octocat") # Check status if response.is_success: data = await response.json() print(f"User: ") # Response provides helpers print(f"Status: ") print(f"Headers: ") print(f"Elapsed: s") finally: # Always close to release connections await client.close() # Or use context manager async def with_context(): async with AsyncHTTPClient() as client: response = await client.get("https://httpbin.org/get") data = await response.json() return data Configuration AsyncHTTPClient supports comprehensive configuration via HTTPClientConfig . All nested configurations are fully configurable: from aquilia.http import ( AsyncHTTPClient, HTTPClientConfig, TimeoutConfig, PoolConfig, RetryConfig, ProxyConfig, TLSConfig ) client = AsyncHTTPClient(HTTPClientConfig( # Base URL (prepended to all relative URLs) base_url="https://api.example.com", # Timeout configuration with granular control timeout=TimeoutConfig( total=30.0, # Overall request timeout (None = no limit) connect=10.0, # Connection establishment timeout read=20.0, # Read timeout for response data write=10.0, # Write timeout for request data pool=5.0, # Pool acquisition timeout ), # Connection pool configuration pool=PoolConfig( max_connections=100, # Global connection limit max_connections_per_host=10, # Per-host connection limit keepalive_expiry=60.0, # Keep-alive duration (seconds) ), # Retry configuration with exponential backoff retry=RetryConfig( max_attempts=3, # Number of retry attempts backoff_base=1.0, # Base delay for backoff backoff_multiplier=2.0, # Exponential backoff multiplier backoff_max=60.0, # Maximum backoff delay backoff_jitter=0.1, # Add randomness to backoff retry_on_status= , # Retry on these status codes retry_on_methods= , # Retry these methods (idempotent) ), # Proxy configuration (supports environment variables) proxy=ProxyConfig( http_proxy="http://proxy.corp:8080", https_proxy="https://proxy.corp:8080", no_proxy="localhost,127.0.0.1,*.local", ), # TLS/SSL configuration tls=TLSConfig( verify=True, # Verify SSL certificates cert_file="/path/to/client.crt", # Client certificate key_file="/path/to/client.key", # Client private key ca_bundle="/path/to/ca.pem", # Custom CA bundle ciphers="ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM", # Cipher suite ), # Default headers for all requests default_headers= , # Redirect handling follow_redirects=True, # Follow 3xx redirects max_redirects=10, # Maximum redirect hops # Error handling raise_for_status=False, # Raise HTTPStatusFault for 4xx/5xx # User agent override user_agent="Aquilia-HTTP/1.0 MyApp/2.1", )) Configuration Presets Use factory methods on TimeoutConfig and RetryConfig for common scenarios: # Fast config for internal APIs config = HTTPClientConfig( timeout=TimeoutConfig.fast(), # total=5.0, connect=2.0 retry=RetryConfig.no_retry(), # max_attempts=0 ) # Slow config for external APIs config = HTTPClientConfig( timeout=TimeoutConfig.slow(), # total=60.0, connect=15.0 retry=RetryConfig.aggressive(), # max_attempts=5, backoff_max=30.0 ) # No timeout for long downloads config = HTTPClientConfig( timeout=TimeoutConfig.no_timeout(), # All timeouts = None ) # Serialize/deserialize config config_dict = config.to_dict() restored = HTTPClientConfig.from_dict(config_dict) Request Methods AsyncHTTPClient provides convenience methods for all HTTP verbs: client = AsyncHTTPClient() # GET request response = await client.get("/users") # POST with JSON body response = await client.post( "/users", json= ) # PUT with custom headers response = await client.put( "/users/123", json= , headers= ) # PATCH response = await client.patch("/users/123", json= ) # DELETE response = await client.delete("/users/123") # HEAD (no body) response = await client.head("/health") # OPTIONS response = await client.options("/api") # Generic request method response = await client.request( "GET", "/custom", headers= , params= , ) Request Parameters All request methods accept these parameters to customize the outgoing request: ))} Query Parameters # Query params as dict response = await client.get( "/search", params= ) # Sends: GET /search?q=python&page=1&limit=10 # URL encoding handled automatically response = await client.get( "/search", params= ) # Sends: GET /search?q=async+programming&tags=python%2Casyncio # Array-like params params = response = await client.get("/users", params=params) # Sends: GET /users?filter=active&filter=verified Headers # Per-request headers response = await client.get( "/api/data", headers= ) # Headers are case-insensitive response = await client.get( "/api/data", headers= # Same as "Accept" ) # Merge with default headers client = AsyncHTTPClient(HTTPClientConfig( default_headers= )) # Request headers merge with defaults response = await client.get("/", headers= ) # Sends: User-Agent: MyApp/1.0, X-Custom: value JSON Requests # JSON is auto-serialized response = await client.post( "/api/users", json= } ) # Automatically sets: # - Content-Type: application/json # - Serializes dict to JSON string # Complex data structures import datetime data = , } response = await client.post("/api/records", json=data) File Uploads and Multipart Forms Supports robust multipart form building with progress callbacks and automatic content type detection via MultipartFormData : from aquilia.http import MultipartFormData from pathlib import Path # Using MultipartFormData builder form = ( MultipartFormData() .field("title", "My Document") .field("description", "A sample file upload") .file("document", "report.pdf", open("report.pdf", "rb")) .file_from_path("image", Path("chart.png")) .file_from_bytes("config", "config.json", b' ', "application/json") ) response = await client.post("/upload", files=form) # Progress tracking with callbacks async def progress_callback(progress): print(f"Uploaded: / " f"( %) at B/s") # Streaming upload for large files from aquilia.http.streaming import StreamingBody stream = StreamingBody( Path("large_file.zip"), chunk_size=65536, on_progress=progress_callback ) form = MultipartFormData().file("upload", "large_file.zip", stream) response = await client.post("/upload", files=form) Authentication Supports 6 built-in authentication schemes implemented as request interceptors: Basic Authentication (RFC 7617) from aquilia.http import BasicAuth auth = BasicAuth("username", "password") client = AsyncHTTPClient(interceptors=[auth]) # Or per-request response = await client.get("/protected", auth=("user", "pass")) Bearer Token Authentication from aquilia.http import BearerAuth # Static token auth = BearerAuth("your-jwt-token") # Dynamic token with callback async def get_token(): return "dynamic-resolved-token" auth = BearerAuth(get_token) # Resolves for each request client = AsyncHTTPClient(interceptors=[auth]) API Key Authentication from aquilia.http import APIKeyAuth # Header-based API key auth = APIKeyAuth("X-API-Key", "your-api-key", location="header") # Query parameter API key auth = APIKeyAuth("api_key", "your-api-key", location="query") client = AsyncHTTPClient(interceptors=[auth]) Digest Authentication (RFC 7616) from aquilia.http import DigestAuth # Automatic challenge-response workflow auth = DigestAuth("username", "password") client = AsyncHTTPClient(interceptors=[auth]) OAuth2 Authentication from aquilia.http import OAuth2Auth auth = OAuth2Auth( client_id="your-client-id", client_secret="your-client-secret", token_url="https://auth.provider.com/oauth/token", initial_token="current-access-token", ) client = AsyncHTTPClient(interceptors=[auth]) AWS Signature V4 Authentication from aquilia.http import AWSSignatureV4Auth auth = AWSSignatureV4Auth( access_key="ACCESS_KEY_EXAMPLE", secret_key="SECRET_KEY_EXAMPLE", region="us-east-1", service="s3" ) client = AsyncHTTPClient(interceptors=[auth]) Streaming Requests and Responses Stream large file uploads or response payloads to minimize memory footprints: Streaming Response Data # Stream response in chunks response = await client.get("https://example.com/large-file.zip") async for chunk in response.iter_bytes(chunk_size=8192): process_chunk(chunk) # Stream response as text lines response = await client.get("https://api.example.com/logs") async for line in response.iter_lines(): parse_log_line(line) # Stream response as text with encoding response = await client.get("https://example.com/data.csv") async for chunk in response.iter_text(chunk_size=4096, encoding="utf-8"): parse_csv_chunk(chunk) Streaming Request Bodies from aquilia.http.streaming import StreamingBody # Stream file upload stream = StreamingBody( Path("large-video.mp4"), chunk_size=65536, ) response = await client.put("/upload/video", data=stream) # Stream from async generator async def generate_data(): for i in range(100): yield f"chunk- \n".encode() stream = StreamingBody(generate_data(), chunk_size=1024) response = await client.post("/stream-data", data=stream) Fault Hierarchy All errors thrown by the HTTP client inherit from HTTPClientFault: HTTPClientFault — Base exception class. ├─ ConnectionFault — TCP/connection handshake errors. ├─ TimeoutFault — Granular Connect/Read/Write timeout errors. │ ├─ ConnectTimeoutFault │ ├─ ReadTimeoutFault │ └─ WriteTimeoutFault ├─ TLSFault — SSL Handshake and cert verification failures. ├─ HTTPStatusFault — Non-2xx status codes (when raise_for_status is True). │ ├─ ClientErrorFault (4xx) │ └─ ServerErrorFault (5xx) ├─ RedirectFault — Redirection loop or limit exceeded. └─ RetryExhaustedFault — Exceeded max retry counts. Overview Sessions )

### Code Examples
```python
from aquilia.http import AsyncHTTPClient

async def main():
    # Create client
    client = AsyncHTTPClient()
    
    try:
        # Make GET request
        response = await client.get("https://api.github.com/users/octocat")
        
        # Check status
        if response.is_success:
            data = await response.json()
            print(f"User: {data['login']}")
        
        # Response provides helpers
        print(f"Status: {response.status_code}")
        print(f"Headers: {response.headers}")
        print(f"Elapsed: {response.elapsed}s")
    
    finally:
        # Always close to release connections
        await client.close()

# Or use context manager
async def with_context():
    async with AsyncHTTPClient() as client:
        response = await client.get("https://httpbin.org/get")
        data = await response.json()
        return data
```

```python
from aquilia.http import (
    AsyncHTTPClient, HTTPClientConfig, TimeoutConfig, PoolConfig, 
    RetryConfig, ProxyConfig, TLSConfig
)

client = AsyncHTTPClient(HTTPClientConfig(
    # Base URL (prepended to all relative URLs)
    base_url="https://api.example.com",
    
    # Timeout configuration with granular control
    timeout=TimeoutConfig(
        total=30.0,       # Overall request timeout (None = no limit)
        connect=10.0,     # Connection establishment timeout
        read=20.0,        # Read timeout for response data
        write=10.0,       # Write timeout for request data
        pool=5.0,         # Pool acquisition timeout
    ),
    
    # Connection pool configuration
    pool=PoolConfig(
        max_connections=100,             # Global connection limit
        max_connections_per_host=10,     # Per-host connection limit  
        keepalive_expiry=60.0,           # Keep-alive duration (seconds)
    ),
    
    # Retry configuration with exponential backoff
    retry=RetryConfig(
        max_attempts=3,                  # Number of retry attempts
        backoff_base=1.0,                # Base delay for backoff
        backoff_multiplier=2.0,          # Exponential backoff multiplier
        backoff_max=60.0,                # Maximum backoff delay
        backoff_jitter=0.1,              # Add randomness to backoff
        retry_on_status={429, 500, 502, 503, 504},  # Retry on these status codes
        retry_on_methods={"GET", "HEAD", "OPTIONS", "PUT", "DELETE"},  # Retry these methods (idempotent)
    ),
    
    # Proxy configuration (supports environment variables)
    proxy=ProxyConfig(
        http_proxy="http://proxy.corp:8080",
        https_proxy="https://proxy.corp:8080", 
        no_proxy="localhost,127.0.0.1,*.local",
    ),
    
    # TLS/SSL configuration
    tls=TLSConfig(
        verify=True,                     # Verify SSL certificates
        cert_file="/path/to/client.crt", # Client certificate
        key_file="/path/to/client.key",  # Client private key
        ca_bundle="/path/to/ca.pem",     # Custom CA bundle
        ciphers="ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM",  # Cipher suite
    ),
    
    # Default headers for all requests
    default_headers={
        "User-Agent": "MyApp/1.0",
        "Accept": "application/json",
        "X-API-Version": "v1",
    },
    
    # Redirect handling
    follow_redirects=True,               # Follow 3xx redirects
    max_redirects=10,                    # Maximum redirect hops
    
    # Error handling
    raise_for_status=False,              # Raise HTTPStatusFault for 4xx/5xx
    
    # User agent override
    user_agent="Aquilia-HTTP/1.0 MyApp/2.1",
))
```

```python
# Fast config for internal APIs
config = HTTPClientConfig(
    timeout=TimeoutConfig.fast(),        # total=5.0, connect=2.0
    retry=RetryConfig.no_retry(),        # max_attempts=0
)

# Slow config for external APIs
config = HTTPClientConfig(
    timeout=TimeoutConfig.slow(),        # total=60.0, connect=15.0
    retry=RetryConfig.aggressive(),      # max_attempts=5, backoff_max=30.0
)

# No timeout for long downloads
config = HTTPClientConfig(
    timeout=TimeoutConfig.no_timeout(),  # All timeouts = None
)

# Serialize/deserialize config
config_dict = config.to_dict()
restored = HTTPClientConfig.from_dict(config_dict)
```



---

## HTTP Sessions
**URL**: `https://tubox.cloud/docs/http/sessions`

HTTP Client / Sessions HTTP Sessions Sessions provide persistent configuration, cookie storage, and connection reuse across multiple HTTP requests. What is a Session? An HTTPSession provides stateful, persistent context across multiple requests with automatic resource management: ))} from aquilia.http import HTTPSession async with HTTPSession() as session: # First request sets authentication cookie await session.post("/login", json= ) # Subsequent requests automatically send cookies + reuse connections profile = await session.get("/profile") settings = await session.get("/settings") await session.post("/update", json=data) Creating Sessions from aquilia.http import HTTPSession, HTTPClientConfig, TimeoutConfig, PoolConfig from aquilia.http import BasicAuth, LoggingInterceptor, CookieMiddleware # Basic session with auto-generated config session = HTTPSession() # Session with comprehensive configuration config = HTTPClientConfig( base_url="https://api.example.com", timeout=TimeoutConfig(total=30.0, connect=10.0), pool=PoolConfig(max_connections=50, max_connections_per_host=10), default_headers= , follow_redirects=True, max_redirects=10, raise_for_status=True, ) session = HTTPSession( config=config, cookies=None, interceptors=[ BasicAuth("user", "password"), ], ) Base URL session = HTTPSession(HTTPClientConfig( base_url="https://api.github.com" )) # Relative paths are appended to base_url users = await session.get("/users") # https://api.github.com/users repos = await session.get("/repos") # https://api.github.com/repos # Absolute URLs override base_url external = await session.get("https://httpbin.org/get") Cookie Management Sessions manage cookies compliant with RFC 6265, handling SameSite, Secure, and HttpOnly attributes: Automatic Cookie Handling session = HTTPSession() # Server sends Set-Cookie header response = await session.post("/login", json= ) # Session automatically stores cookie in CookieJar profile = await session.get("/profile") # Sends Cookie header # Cookies are domain/path scoped await session.get("https://other-domain.com/api") # No cookie sent Connection Management Connections are reused to reduce handshake overhead and TLS setup latency: from aquilia.http import HTTPSession, PoolConfig, HTTPClientConfig session = HTTPSession(HTTPClientConfig( pool=PoolConfig( max_connections=100, max_connections_per_host=10, keepalive_expiry=60.0, ) )) await session.get("https://api.example.com/users") # Establishes TCP connection await session.get("https://api.example.com/posts") # Reuses TCP connection Session vs HTTPClient While both make async requests, choose them based on lifetime requirements: Use HTTPSession when: Making multiple sequential calls to the same host, keeping login cookies, or sharing a connection pool. Use HTTPClient when: Performing isolated, one-off operations or accessing diverse external endpoints with unique request configurations. HTTPClient Transport Layer )

### Code Examples
```python
from aquilia.http import HTTPSession

async with HTTPSession() as session:
    # First request sets authentication cookie  
    await session.post("/login", json={"user": "alice", "pass": "secret"})
    
    # Subsequent requests automatically send cookies + reuse connections
    profile = await session.get("/profile")
    settings = await session.get("/settings")
    await session.post("/update", json=data)
```

```python
from aquilia.http import HTTPSession, HTTPClientConfig, TimeoutConfig, PoolConfig
from aquilia.http import BasicAuth, LoggingInterceptor, CookieMiddleware

# Basic session with auto-generated config
session = HTTPSession()

# Session with comprehensive configuration
config = HTTPClientConfig(
    base_url="https://api.example.com",
    timeout=TimeoutConfig(total=30.0, connect=10.0),
    pool=PoolConfig(max_connections=50, max_connections_per_host=10),
    default_headers={
        "User-Agent": "MyApp/1.0",
        "Accept": "application/json",
    },
    follow_redirects=True,
    max_redirects=10,
    raise_for_status=True,
)

session = HTTPSession(
    config=config,
    cookies=None,
    interceptors=[
        BasicAuth("user", "password"),
    ],
)
```

```python
session = HTTPSession(HTTPClientConfig(
    base_url="https://api.github.com"
))

# Relative paths are appended to base_url
users = await session.get("/users")  # https://api.github.com/users
repos = await session.get("/repos")  # https://api.github.com/repos

# Absolute URLs override base_url
external = await session.get("https://httpbin.org/get")
```



---

## Transport Layer
**URL**: `https://tubox.cloud/docs/http/transport`

HTTP Client / Internals Transport Layer The NativeTransport implements HTTP/1.1 protocol handling using pure Python asyncio — no external HTTP client dependencies. Architecture The transport layer is the foundation of Aquilia&apos;s HTTP client: HTTPClient ↓ Uses Session ↓ Uses NativeTransport ├─ ConnectionPool (connection reuse) ├─ HTTP/1.1 protocol implementation ├─ Chunked transfer encoding ├─ Gzip/deflate decompression ├─ SSL/TLS handling └─ Fault conversion Why Native Transport? Zero External Dependencies Built entirely on Python&apos;s standard library (asyncio, ssl, gzip, zlib). No need for aiohttp, or other third-party HTTP clients. Deep Integration Tight coupling with Aquilia&apos;s fault system. Network errors are automatically converted to typed faults (ConnectionFault, TimeoutFault, TLSFault) with structured metadata. HTTP/1.1 Protocol NativeTransport implements the HTTP/1.1 specification: • Persistent connections — Keep-alive for connection reuse. • Chunked encoding — Streaming without Content-Length headers. # Request format (what NativeTransport sends) GET /api/users HTTP/1.1\r Host: api.example.com\r User-Agent: Aquilia-HTTP/1.0\r Connection: keep-alive\r \r # Response format (what NativeTransport receives) HTTP/1.1 200 OK\r Content-Type: application/json\r Content-Length: 42\r Connection: keep-alive\r \r Connection Pooling # Internal structure (simplified) class ConnectionPool: def __init__(self, max_connections: int, keepalive_expiry: float): self._pool: dict[str, list[ConnectionInfo]] = self._max_connections = max_connections self._keepalive_expiry = keepalive_expiry async def acquire( self, scheme: str, host: str, port: int, ssl_context: ssl.SSLContext | None, ) -> tuple[StreamReader, StreamWriter]: key = f" :// : " # Try pool first if key in self._pool: for conn in self._pool[key]: if self._is_alive(conn): return conn.reader, conn.writer # Create new connection reader, writer = await asyncio.open_connection( host, port, ssl=ssl_context ) return reader, writer SSL/TLS Handling HTTPS connections are managed via Python&apos;s native ssl context: import ssl # Create SSL context from config if config.verify_ssl: ssl_context = ssl.create_default_context() else: ssl_context = ssl._create_unverified_context() # Connect with TLS reader, writer = await asyncio.open_connection( host, port, ssl=ssl_context, server_hostname=host, ) Performance Connection Reuse Keep-alive sockets avoid TCP handshake (~100ms) and TLS negotiation (~200ms) on repeat requests. Memory Efficiency Streaming response chunks prevents loading large file payloads fully into Python process memory. Sessions Advanced Usage )

### Code Examples
```python
# Request format (what NativeTransport sends)
GET /api/users HTTP/1.1\r
Host: api.example.com\r
User-Agent: Aquilia-HTTP/1.0\r
Connection: keep-alive\r
\r

# Response format (what NativeTransport receives)
HTTP/1.1 200 OK\r
Content-Type: application/json\r
Content-Length: 42\r
Connection: keep-alive\r
\r
{"users": ["alice", "bob"]}
```

```python
# Internal structure (simplified)
class ConnectionPool:
    def __init__(self, max_connections: int, keepalive_expiry: float):
        self._pool: dict[str, list[ConnectionInfo]] = {}
        self._max_connections = max_connections
        self._keepalive_expiry = keepalive_expiry
    
    async def acquire(
        self,
        scheme: str,
        host: str,
        port: int,
        ssl_context: ssl.SSLContext | None,
    ) -> tuple[StreamReader, StreamWriter]:
        key = f"{scheme}://{host}:{port}"
        
        # Try pool first
        if key in self._pool:
            for conn in self._pool[key]:
                if self._is_alive(conn):
                    return conn.reader, conn.writer
        
        # Create new connection
        reader, writer = await asyncio.open_connection(
            host, port, ssl=ssl_context
        )
        return reader, writer
```

```python
import ssl

# Create SSL context from config
if config.verify_ssl:
    ssl_context = ssl.create_default_context()
else:
    ssl_context = ssl._create_unverified_context()

# Connect with TLS
reader, writer = await asyncio.open_connection(
    host,
    port,
    ssl=ssl_context,
    server_hostname=host,
)
```



---

## Advanced Usage
**URL**: `https://tubox.cloud/docs/http/advanced`

HTTP Client / Advanced Advanced Usage Advanced HTTP client features: streaming, retry strategies, interceptors, and middleware. Streaming Responses Process large response payloads without loading the entire body into memory: client = AsyncHTTPClient() # Stream response body bytes response = await client.get("https://example.com/large-file.csv") async for chunk in response.iter_bytes(chunk_size=8192): # Process chunk (bytes) process_data(chunk) # Stream to file response = await client.get("https://example.com/video.mp4") with open("video.mp4", "wb") as f: async for chunk in response.iter_bytes(): f.write(chunk) # Stream lines (text) response = await client.get("https://example.com/logs.txt") async for line in response.iter_lines(): # Each line is decoded as UTF-8 print(f"Log: ") # Stream JSON lines (JSONL/NDJSON) response = await client.get("https://api.example.com/stream") async for line in response.iter_lines(): if line.strip(): record = json.loads(line) process_record(record) Streaming Requests Stream large file uploads or generators to minimize memory footprint: # Stream file upload without loading into memory async def file_stream(): with open("large-file.bin", "rb") as f: while chunk := f.read(1024 * 64): yield chunk response = await client.post( "/upload", data=file_stream(), headers= , ) # Stream generated data async def data_generator(): for i in range(100): yield f"Line \n".encode() response = await client.post("/stream-upload", data=data_generator()) Retry Strategies Configure automatic retries with exponential backoff for transient failures using RetryConfig : from aquilia.http import AsyncHTTPClient, RetryConfig client = AsyncHTTPClient(HTTPClientConfig( retry=RetryConfig( max_attempts=3, # Retry up to 3 times backoff_base=1.0, # Exponential backoff base delay (seconds) backoff_max=30.0, # Cap backoff delay retry_on_status= , ), )) Interceptors Hook actions that execute before a request is sent, or after a response is received: from aquilia.http.interceptors import HTTPInterceptor # Logging interceptor class LoggingInterceptor(HTTPInterceptor): async def intercept(self, request, handler): print(f"→ ") response = await handler(request) print(f"← ") return response client = AsyncHTTPClient(interceptors=[ LoggingInterceptor(), ]) Concurrent Requests import asyncio client = AsyncHTTPClient() urls = [ "https://api.example.com/users/1", "https://api.example.com/users/2", ] responses = await asyncio.gather(*[ client.get(url) for url in urls ]) # Limit concurrency with semaphore semaphore = asyncio.Semaphore(5) async def fetch(url: str): async with semaphore: return await client.get(url) Proxy Support # HTTP proxy client = AsyncHTTPClient(HTTPClientConfig( proxy=ProxyConfig(http_proxy="http://proxy.example.com:8080"), )) # Environment variable fallback import os os.environ["HTTP_PROXY"] = "http://proxy.example.com:8080" client = AsyncHTTPClient() Transport Layer Error Handling )

### Code Examples
```python
client = AsyncHTTPClient()

# Stream response body bytes
response = await client.get("https://example.com/large-file.csv")

async for chunk in response.iter_bytes(chunk_size=8192):
    # Process chunk (bytes)
    process_data(chunk)

# Stream to file
response = await client.get("https://example.com/video.mp4")
with open("video.mp4", "wb") as f:
    async for chunk in response.iter_bytes():
        f.write(chunk)

# Stream lines (text)
response = await client.get("https://example.com/logs.txt")
async for line in response.iter_lines():
    # Each line is decoded as UTF-8
    print(f"Log: {line}")

# Stream JSON lines (JSONL/NDJSON)
response = await client.get("https://api.example.com/stream")
async for line in response.iter_lines():
    if line.strip():
        record = json.loads(line)
        process_record(record)
```

```python
# Stream file upload without loading into memory
async def file_stream():
    with open("large-file.bin", "rb") as f:
        while chunk := f.read(1024 * 64):
            yield chunk

response = await client.post(
    "/upload",
    data=file_stream(),
    headers={"Content-Type": "application/octet-stream"},
)

# Stream generated data
async def data_generator():
    for i in range(100):
        yield f"Line {i}\n".encode()

response = await client.post("/stream-upload", data=data_generator())
```

```python
from aquilia.http import AsyncHTTPClient, RetryConfig

client = AsyncHTTPClient(HTTPClientConfig(
    retry=RetryConfig(
        max_attempts=3,          # Retry up to 3 times
        backoff_base=1.0,        # Exponential backoff base delay (seconds)
        backoff_max=30.0,        # Cap backoff delay
        retry_on_status={408, 429, 500, 502, 503, 504},
    ),
))
```



---

## Fault System
**URL**: `https://tubox.cloud/docs/http/faults`

HTTP Client / Error Handling Fault System Structured error handling with typed faults, metadata, and domain-specific error codes. Why Faults? Aquilia uses structured faults instead of raw exceptions for better error handling: ))} Fault Hierarchy Fault (base class for all Aquilia errors) └─ HTTPClientFault (domain: HTTP_CLIENT) ├─ ConnectionFault (CONNECTION_FAILED) ├─ TimeoutFault (TIMEOUT) │ ├─ ConnectTimeoutFault (CONNECT_TIMEOUT) │ ├─ ReadTimeoutFault (READ_TIMEOUT) │ └─ WriteTimeoutFault (WRITE_TIMEOUT) ├─ TLSFault (TLS_ERROR) │ └─ CertificateVerifyFault (CERT_VERIFY_FAILED) ├─ HTTPStatusFault (HTTP_STATUS_ERROR) │ ├─ ClientErrorFault (4xx) │ └─ ServerErrorFault (5xx) ├─ RetryExhaustedFault (RETRY_EXHAUSTED) ├─ RedirectFault (TOO_MANY_REDIRECTS) └─ TransportFault (TRANSPORT_ERROR) ConnectionFault Raised when a TCP socket connection fails: from aquilia.http.faults import ConnectionFault try: response = await client.get("https://nonexistent-host.invalid") except ConnectionFault as e: print(f"Code: ") # CONNECTION_FAILED print(f"Message: ") # "Connection failed: ..." print(f"Domain: ") # HTTP_CLIENT # Metadata print(f"Host: ") print(f"Port: ") TimeoutFault Raised when a network operation exceeds a defined timeout limit: from aquilia.http.faults import ( TimeoutFault, ConnectTimeoutFault, ReadTimeoutFault, ) try: response = await client.get("https://slow-api.com") except TimeoutFault as e: print(f"Timeout: s") print(f"Phase: ") # connect/read/write try: response = await client.get("https://slow-connect.com") except ConnectTimeoutFault: print("Connection timed out") TLSFault Raised for SSL/TLS handshaking or validation errors: from aquilia.http.faults import TLSFault, CertificateVerifyFault try: response = await client.get("https://expired-cert.badssl.com") except TLSFault as e: print(f"TLS error: ") try: response = await client.get("https://self-signed.badssl.com") except CertificateVerifyFault as e: print("Certificate verification failed") HTTPStatusFault Raised for non-2xx status codes when using raise_for_status(): from aquilia.http.faults import HTTPStatusFault, ClientErrorFault, ServerErrorFault response = await client.get("/api/users/9999") try: response.raise_for_status() except HTTPStatusFault as e: print(f"Status: ") # 404 print(f"Message: ") # "HTTP 404: Not Found" try: response = await client.get("/api/protected") response.raise_for_status() except ClientErrorFault as e: if e.status_code == 401: print("Unauthorized") Advanced Usage DI Integration )

### Code Examples
```python
from aquilia.http.faults import ConnectionFault

try:
    response = await client.get("https://nonexistent-host.invalid")
except ConnectionFault as e:
    print(f"Code: {e.code}")           # CONNECTION_FAILED
    print(f"Message: {e.message}")     # "Connection failed: ..."
    print(f"Domain: {e.domain}")       # HTTP_CLIENT
    
    # Metadata
    print(f"Host: {e.metadata['host']}")
    print(f"Port: {e.metadata['port']}")
```

```python
from aquilia.http.faults import (
    TimeoutFault,
    ConnectTimeoutFault,
    ReadTimeoutFault,
)

try:
    response = await client.get("https://slow-api.com")
except TimeoutFault as e:
    print(f"Timeout: {e.metadata['timeout']}s")
    print(f"Phase: {e.metadata.get('phase')}")  # connect/read/write

try:
    response = await client.get("https://slow-connect.com")
except ConnectTimeoutFault:
    print("Connection timed out")
```

```python
from aquilia.http.faults import TLSFault, CertificateVerifyFault

try:
    response = await client.get("https://expired-cert.badssl.com")
except TLSFault as e:
    print(f"TLS error: {e.message}")

try:
    response = await client.get("https://self-signed.badssl.com")
except CertificateVerifyFault as e:
    print("Certificate verification failed")
```



---

## Aquilia Integration
**URL**: `https://tubox.cloud/docs/http/integration`

HTTP Client / Integration Aquilia Integration Using the HTTP client within Aquilia: dependency injection, config builders, and integration with other subsystems. Dependency Injection The AsyncHTTPClient integrates seamlessly with Aquilia&apos;s DI container: from aquilia import Controller, RequestCtx, Response from aquilia.http import AsyncHTTPClient class UsersController(Controller): prefix = "/users" def __init__(self, http: AsyncHTTPClient): self.http = http async def get_user_data(self, ctx: RequestCtx): response = await self.http.get("https://api.github.com/users/octocat") user_data = await response.json() return Response.json(user_data) Configuration via Workspace Configure HTTP clients in your workspace.py: from aquilia import Workspace, Integration from aquilia.http import HTTPClientConfig, TimeoutConfig, RetryConfig, PoolConfig workspace = Workspace( integrations=[ # Configure default HTTP client Integration.http_client( config=HTTPClientConfig( timeout=TimeoutConfig(total=30.0), pool=PoolConfig(max_connections=100), ), ), # Named HTTP client for specific API Integration.http_client( name="github_client", config=HTTPClientConfig( base_url="https://api.github.com", ), ), ], ) Provider Scopes HTTP clients can be registered with different DI scopes: Singleton (default) One client instance shared across the entire app lifecycle. This is highly recommended to benefit from connection pooling reuse. Request Scope Creates a new client instance per request. Use with caution as it destroys pooling efficiency. Error Handling )

### Code Examples
```python
from aquilia import Controller, RequestCtx, Response
from aquilia.http import AsyncHTTPClient

class UsersController(Controller):
    prefix = "/users"
    
    def __init__(self, http: AsyncHTTPClient):
        self.http = http
    
    async def get_user_data(self, ctx: RequestCtx):
        response = await self.http.get("https://api.github.com/users/octocat")
        user_data = await response.json()
        return Response.json(user_data)
```

```python
from aquilia import Workspace, Integration
from aquilia.http import HTTPClientConfig, TimeoutConfig, RetryConfig, PoolConfig

workspace = Workspace(
    integrations=[
        # Configure default HTTP client
        Integration.http_client(
            config=HTTPClientConfig(
                timeout=TimeoutConfig(total=30.0),
                pool=PoolConfig(max_connections=100),
            ),
        ),
        
        # Named HTTP client for specific API
        Integration.http_client(
            name="github_client",
            config=HTTPClientConfig(
                base_url="https://api.github.com",
            ),
        ),
    ],
)
```



---

## request.py
**URL**: `https://tubox.cloud/docs/http/api`

HTTP Client / Core API request.py Low-level request construction primitives for AquilaHTTP. This module defines immutable request objects, URL/header/body validation, and the request builder used by AsyncHTTPClient and HTTPSession . 1. Overview request.py is the canonical request-shaping boundary for the HTTP client subsystem. It is split into two layers: • HTTPClientRequest: immutable payload consumed by transport and interception stacks. • RequestBuilder: mutable fluent DSL that validates and materializes HTTPClientRequest. 2. Architecture and Design • RequestBuilder stores mutable assembly state in private slots for low-overhead chaining. • build() emits HTTPClientRequest dataclass instances to isolate downstream processing from mutation. • Header names/values are validated to prevent malformed request lines and header injection issues. • JSON/form serialization occurs at build time, not transport time, so faults are deterministic. 3. API Reference class HTTPMethod(str, Enum): GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE, CONNECT HeadersType = Mapping[str, str] | list[tuple[str, str]] | None ParamsType = Mapping[str, str | int | float | bool | None] | list[tuple[str, str]] | None CookiesType = Mapping[str, str] | None DataType = Mapping[str, Any] | str | bytes | None JsonType = Any ContentType = str | bytes | AsyncIterator[bytes] | BinaryIO | None def _normalize_header_name(name: str) -> str: # Title-Case normalization return name.title() def _validate_header_name(name: str) -> None: # Raises InvalidHeaderFault on empty or control chars pass 4. Hardening and Edge Cases • Dotted keys and complex query structures are fully supported and urlencoded automatically. • Request headers are strictly validated to prevent CR-LF injection vectors. )

### Code Examples
```python
class HTTPMethod(str, Enum):
    GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE, CONNECT

HeadersType = Mapping[str, str] | list[tuple[str, str]] | None
ParamsType = Mapping[str, str | int | float | bool | None] | list[tuple[str, str]] | None
CookiesType = Mapping[str, str] | None
DataType = Mapping[str, Any] | str | bytes | None
JsonType = Any
ContentType = str | bytes | AsyncIterator[bytes] | BinaryIO | None
```

```python
def _normalize_header_name(name: str) -> str:
    # Title-Case normalization
    return name.title()

def _validate_header_name(name: str) -> None:
    # Raises InvalidHeaderFault on empty or control chars
    pass
```



---

## response.py
**URL**: `https://tubox.cloud/docs/http/api/response`

HTTP Client / Core API response.py Immutable response envelope with lazy body consumption, streaming iterators, text/JSON decoding helpers, status classification, and fault-aware status escalation. 1. Overview response.py is the terminal read model for outbound HTTP execution. It provides a single object that supports both buffered and streaming usage patterns. 2. Architecture and Design • Headers are stored as dictionaries supporting case-insensitive lookups. • Body can be pre-buffered or lazy-streamed with one-time consumption semantics. 3. API Reference {`@dataclass class HTTPClientResponse: status_code: int headers: dict[str, str] url: str http_version: str = "1.1" elapsed: float = 0.0 history: list[HTTPClientResponse] = field(default_factory=list) _body: bytes | None = None _stream: AsyncIterator[bytes] | None = None @property def is_success(self) -> bool: return 200 )

### Code Examples
```python
@dataclass
class HTTPClientResponse:
    status_code: int
    headers: dict[str, str]
    url: str
    http_version: str = "1.1"
    elapsed: float = 0.0
    history: list[HTTPClientResponse] = field(default_factory=list)

    _body: bytes | None = None
    _stream: AsyncIterator[bytes] | None = None

    @property
    def is_success(self) -> bool:
        return 200 <= self.status_code < 300
```



---

## auth.py
**URL**: `https://tubox.cloud/docs/http/api/auth`

HTTP Client / Core API auth.py Outbound authentication interceptors for HTTP requests: Basic, Bearer, API Key, Digest, OAuth2 token refresh, and AWS Signature V4 request signing. 1. Overview auth.py implements authentication as HTTPInterceptor-compatible units. 2. API Reference class AuthInterceptor(HTTPInterceptor, ABC): @abstractmethod def get_auth_header(self, request: HTTPClientRequest) -> tuple[str, str] | None async def intercept( self, request: HTTPClientRequest, next_handler: Callable[[HTTPClientRequest], Awaitable[HTTPClientResponse]], ) -> HTTPClientResponse class BasicAuth(AuthInterceptor): def __init__(self, username: str, password: str) class BearerAuth(AuthInterceptor): def __init__(self, token: str | None = None, token_getter: Callable[[], str] | None = None) class APIKeyAuth(AuthInterceptor): def __init__(self, key: str, header_name: str = "X-API-Key", in_query: bool = False) )

### Code Examples
```python
class AuthInterceptor(HTTPInterceptor, ABC):
    @abstractmethod
    def get_auth_header(self, request: HTTPClientRequest) -> tuple[str, str] | None

    async def intercept(
        self,
        request: HTTPClientRequest,
        next_handler: Callable[[HTTPClientRequest], Awaitable[HTTPClientResponse]],
    ) -> HTTPClientResponse
```

```python
class BasicAuth(AuthInterceptor):
    def __init__(self, username: str, password: str)

class BearerAuth(AuthInterceptor):
    def __init__(self, token: str | None = None, token_getter: Callable[[], str] | None = None)

class APIKeyAuth(AuthInterceptor):
    def __init__(self, key: str, header_name: str = "X-API-Key", in_query: bool = False)
```



---

## cookies.py
**URL**: `https://tubox.cloud/docs/http/api/cookies`

HTTP Client / Core API cookies.py RFC 6265 compliant Cookie and CookieJar primitives for managing HTTP cookies. 1. Overview cookies.py manages cookie attributes (SameSite, Secure, HttpOnly), domain matching, and path hierarchies. 2. API Reference @dataclass class Cookie: name: str value: str domain: str | None = None path: str | None = None expires: datetime | None = None max_age: int | None = None secure: bool = False http_only: bool = False same_site: str | None = None )

### Code Examples
```python
@dataclass
class Cookie:
    name: str
    value: str
    domain: str | None = None
    path: str | None = None
    expires: datetime | None = None
    max_age: int | None = None
    secure: bool = False
    http_only: bool = False
    same_site: str | None = None
```



---

## middleware.py
**URL**: `https://tubox.cloud/docs/http/api/middleware`

HTTP Client / Core API middleware.py Composable onion-model middleware layers for wrapping outbound HTTP request-response cycles. 1. Overview middleware.py handles request processing and response interception in an onion-like flow. 2. API Reference class HTTPClientMiddleware(ABC): @abstractmethod async def __call__( self, request: HTTPClientRequest, next_call: Callable[[HTTPClientRequest], Awaitable[HTTPClientResponse]], ) -> HTTPClientResponse )

### Code Examples
```python
class HTTPClientMiddleware(ABC):
    @abstractmethod
    async def __call__(
        self,
        request: HTTPClientRequest,
        next_call: Callable[[HTTPClientRequest], Awaitable[HTTPClientResponse]],
    ) -> HTTPClientResponse
```



---

## multipart.py
**URL**: `https://tubox.cloud/docs/http/api/multipart`

HTTP Client / Core API multipart.py Outbound multipart form encoding and file upload primitives for HTTP requests. 1. Overview multipart.py parses form boundary properties, file inputs, and compiles boundary data. 2. API Reference class MultipartFormData: def __init__(self, boundary: str | None = None) def field(self, name: str, value: str) -> "MultipartFormData" def file(self, name: str, filename: str, content: bytes | BinaryIO) -> "MultipartFormData" )

### Code Examples
```python
class MultipartFormData:
    def __init__(self, boundary: str | None = None)

    def field(self, name: str, value: str) -> "MultipartFormData"
    def file(self, name: str, filename: str, content: bytes | BinaryIO) -> "MultipartFormData"
```



---

## streaming.py
**URL**: `https://tubox.cloud/docs/http/api/streaming`

HTTP Client / Core API streaming.py Asynchronous request-body and response-body streaming primitives for AquilaHTTP. 1. Overview streaming.py defines progress callbacks, backpressure mechanisms, and streaming helpers. 2. API Reference class StreamingBody: def __init__( self, generator: AsyncIterator[bytes] | BinaryIO, chunk_size: int = 8192, on_progress: Callable[[UploadProgress], None] | None = None, ) )

### Code Examples
```python
class StreamingBody:
    def __init__(
        self,
        generator: AsyncIterator[bytes] | BinaryIO,
        chunk_size: int = 8192,
        on_progress: Callable[[UploadProgress], None] | None = None,
    )
```



---

## Internationalization (i18n)
**URL**: `https://tubox.cloud/docs/i18n`

Advanced / i18n Internationalization (i18n) Aquilia i18n is an async-native localization subsystem with locale negotiation, plural-aware translation lookup, flexible catalog backends, and first-class integration into middleware, templates, DI containers, and CLI workflows. What You Get ))} Workspace-Level Integration Initialize i18n globally in your workspace configuration. You can configure available locales, directory paths, catalog formats, and the locale resolver preference chain. from aquilia import Workspace from aquilia.integrations.i18n import I18nIntegration workspace = ( Workspace("localized-app") .integrate(I18nIntegration( default_locale="en", available_locales=["en", "es", "fr", "ja"], catalog_dirs=["locales"], resolver_order=["query", "cookie", "header"], )) ) Manifest & Module Integration Controllers and services declared in the AppManifest can request the I18nService via constructor dependency injection. You can also define module-level constants using lazy translation utilities. from aquilia import Controller, GET, RequestCtx from aquilia.i18n import I18nService, lazy_t # Constant resolved lazily when the request locale is available BILLING_HEADER = lazy_t("billing.invoice_header") class BillingController(Controller): def __init__(self, i18n: I18nService): self.i18n = i18n @GET("/invoice") async def get_invoice(self, ctx: RequestCtx): locale = ctx.request.state.get("locale", "en") message = self.i18n.t( "billing.invoice_ready", locale=locale, amount="$45.00" ) return Request State Contract State Key Type Meaning locale str Resolved BCP 47 locale tag after negotiating candidate headers/cookies. locale_obj Locale Parsed Locale model with validation, normalization, and fallback properties. i18n I18nService Primary translation and formatting service registry bound to the active request context. Documentation Map ))} )

### Code Examples
```python
from aquilia import Workspace
from aquilia.integrations.i18n import I18nIntegration

workspace = (
    Workspace("localized-app")
    .integrate(I18nIntegration(
        default_locale="en",
        available_locales=["en", "es", "fr", "ja"],
        catalog_dirs=["locales"],
        resolver_order=["query", "cookie", "header"],
    ))
)
```

```python
from aquilia import Controller, GET, RequestCtx
from aquilia.i18n import I18nService, lazy_t

# Constant resolved lazily when the request locale is available
BILLING_HEADER = lazy_t("billing.invoice_header")

class BillingController(Controller):
    def __init__(self, i18n: I18nService):
        self.i18n = i18n

    @GET("/invoice")
    async def get_invoice(self, ctx: RequestCtx):
        locale = ctx.request.state.get("locale", "en")
        
        message = self.i18n.t(
            "billing.invoice_ready",
            locale=locale,
            amount="$45.00"
        )
        return {"header": str(BILLING_HEADER), "message": message}
```



---

## i18n Runtime Architecture
**URL**: `https://tubox.cloud/docs/i18n/architecture`

i18n / Architecture i18n Runtime Architecture Aquilia i18n bootstraps during server startup and then runs as a request-aware translation pipeline. The architecture combines config, catalog loading, locale resolution, formatting, and fault-aware lookup. Boot Sequence # 1) Load merged runtime config raw_i18n = config_loader.get_i18n_config() # 2) Convert to typed config cfg = I18nConfig.from_dict(raw_i18n) # 3) Build i18n service + catalog backend service = create_i18n_service(cfg) # 4) Register app-scoped DI values register_i18n_providers(container, service, cfg) # 5) Build locale resolver chain resolver = build_resolver(cfg) # 6) Add request middleware middleware_stack.add(I18nMiddleware(service, resolver), priority=24) Subsystem Map Component Location Role ))} Translation Lookup Pipeline # t(key, locale) lookup order 1. catalog.get(key, exact_locale) 2. locale fallback chain (for example fr-CA -> fr) 3. catalog.get(key, fallback_locale) 4. missing-key strategy (_handle_missing) # tn(key, count, locale) adds plural selection category = select_plural(lang, count) value = catalog.get_plural(key, locale, category) Locale Resolution Pipeline locale = config.default_locale resolved = chain_resolver.resolve(request) if resolved and service.is_available(resolved): locale = resolved request.state["locale"] = locale request.state["locale_obj"] = parse_locale(locale) request.state["i18n"] = service Boundaries and Contracts • i18n handles localization and translations, not authentication or security authorizations. • The lazy_t translation helper defers actual lookup until string evaluation, preventing early initialization issues during package import. )

### Code Examples
```python
# 1) Load merged runtime config
raw_i18n = config_loader.get_i18n_config()

# 2) Convert to typed config
cfg = I18nConfig.from_dict(raw_i18n)

# 3) Build i18n service + catalog backend
service = create_i18n_service(cfg)

# 4) Register app-scoped DI values
register_i18n_providers(container, service, cfg)

# 5) Build locale resolver chain
resolver = build_resolver(cfg)

# 6) Add request middleware
middleware_stack.add(I18nMiddleware(service, resolver), priority=24)
```

```python
# t(key, locale) lookup order
1. catalog.get(key, exact_locale)
2. locale fallback chain (for example fr-CA -> fr)
3. catalog.get(key, fallback_locale)
4. missing-key strategy (_handle_missing)

# tn(key, count, locale) adds plural selection
category = select_plural(lang, count)
value = catalog.get_plural(key, locale, category)
```

```python
locale = config.default_locale

resolved = chain_resolver.resolve(request)
if resolved and service.is_available(resolved):
    locale = resolved

request.state["locale"] = locale
request.state["locale_obj"] = parse_locale(locale)
request.state["i18n"] = service
```



---

## i18n Configuration
**URL**: `https://tubox.cloud/docs/i18n/configuration`

i18n / Configuration i18n Configuration i18n settings can be declared through workspace builders, typed integration objects, or raw runtime config. At server boot, all paths are normalized into I18nConfig . Configuration Entry Points from aquilia.config_builders import Workspace, Integration from aquilia.integrations.i18n import I18nIntegration workspace = ( Workspace("myapp") # Builder API .integrate( Integration.i18n( enabled=True, default_locale="en", available_locales=["en", "fr", "de", "ja"], fallback_locale="en", catalog_dirs=["locales"], catalog_format="surp", ) ) # Typed integration object .integrate( I18nIntegration( enabled=True, default_locale="en", available_locales=["en", "fr"], catalog_dirs=["locales"], ) ) ) Runtime Precedence # Effective flow # 1) user config in i18n or integrations.i18n # 2) merged with ConfigLoader.get_i18n_config defaults # 3) converted by I18nConfig.from_dict # 4) consumed by create_i18n_service If enabled is false after merge, server setup skips I18nService creation, resolver chain construction, and middleware insertion. Key Reference Key Type Description ))} Default Value Matrix Key ConfigLoader Integration.i18n I18nConfig dataclass from_dict fallback ))} Missing-Key Strategies return_key # returns the dotted key return_empty # returns "" return_default # returns default argument if present, else key raise # raises MissingTranslationFault log_and_key # logs warning and returns key )

### Code Examples
```python
from aquilia.config_builders import Workspace, Integration
from aquilia.integrations.i18n import I18nIntegration

workspace = (
    Workspace("myapp")
    # Builder API
    .integrate(
        Integration.i18n(
            enabled=True,
            default_locale="en",
            available_locales=["en", "fr", "de", "ja"],
            fallback_locale="en",
            catalog_dirs=["locales"],
            catalog_format="surp",
        )
    )

    # Typed integration object
    .integrate(
        I18nIntegration(
            enabled=True,
            default_locale="en",
            available_locales=["en", "fr"],
            catalog_dirs=["locales"],
        )
    )
)
```

```python
# Effective flow
# 1) user config in i18n or integrations.i18n
# 2) merged with ConfigLoader.get_i18n_config defaults
# 3) converted by I18nConfig.from_dict
# 4) consumed by create_i18n_service
```

```python
return_key     # returns the dotted key
return_empty   # returns ""
return_default # returns default argument if present, else key
raise          # raises MissingTranslationFault
log_and_key    # logs warning and returns key
```



---

## i18n Integration Guide
**URL**: `https://tubox.cloud/docs/i18n/integration`

i18n / Integration i18n Integration Guide i18n is integrated at server startup, then exposed through middleware state, template helpers, and DI providers. This page covers default wiring and manual integration patterns. Server-Level Wiring cfg = I18nConfig.from_dict(config_loader.get_i18n_config()) service = create_i18n_service(cfg) register_i18n_providers(container, service, cfg) resolver = build_resolver(cfg) middleware_stack.add(I18nMiddleware(service, resolver), priority=24) register_i18n_template_globals(template_env, service) When enabled=True, the resolved locale and I18nService context become available in the request state dict for all downstream handlers. Middleware Order and State Contract # I18nMiddleware at priority 24 # request.state after middleware: request.state["locale"] # str request.state["locale_obj"] # Locale request.state["i18n"] # I18nService from aquilia import Controller, GET, RequestCtx class WelcomeController(Controller): @GET("/welcome") async def welcome(self, ctx: RequestCtx): i18n = ctx.request.state["i18n"] locale = ctx.request.state.get("locale", "en") return Template Integration } } } } } Template globals automatically bound to the Jinja sandbox environment include _, _n, _p, and filters include translate, format_number, format_currency, and format_date. DI Integration # App-scope registration register_i18n_providers(container, service, config) # Request-scope locale registration register_i18n_request_providers(request_container, locale, service) Manual Integration Pattern from aquilia.i18n.service import I18nConfig, create_i18n_service from aquilia.i18n.middleware import I18nMiddleware, build_resolver from aquilia.i18n.di_integration import register_i18n_providers from aquilia.i18n.template_integration import register_i18n_template_globals cfg = I18nConfig(default_locale="en", available_locales=["en", "fr"], catalog_dirs=["locales"]) svc = create_i18n_service(cfg) register_i18n_providers(app_container, svc, cfg) resolver = build_resolver(cfg) middleware_stack.add(I18nMiddleware(svc, resolver), scope="global", priority=24, name="i18n") register_i18n_template_globals(template_env, svc) )

### Code Examples
```python
cfg = I18nConfig.from_dict(config_loader.get_i18n_config())
service = create_i18n_service(cfg)
register_i18n_providers(container, service, cfg)
resolver = build_resolver(cfg)
middleware_stack.add(I18nMiddleware(service, resolver), priority=24)
register_i18n_template_globals(template_env, service)
```

```python
# I18nMiddleware at priority 24
# request.state after middleware:
request.state["locale"]      # str
request.state["locale_obj"]  # Locale
request.state["i18n"]        # I18nService
```

```python
from aquilia import Controller, GET, RequestCtx

class WelcomeController(Controller):
    @GET("/welcome")
    async def welcome(self, ctx: RequestCtx):
        i18n = ctx.request.state["i18n"]
        locale = ctx.request.state.get("locale", "en")
        return {
            "message": i18n.t("messages.welcome", locale=locale, name="World"),
            "count": i18n.tn("messages.items", 3, locale=locale),
        }
```



---

## i18n API Reference
**URL**: `https://tubox.cloud/docs/i18n/api-reference`

i18n / API Reference i18n API Reference Module-level symbol map for Aquilia i18n including locale utilities, catalog backends, formatting surface, runtime middleware, template wiring, DI hooks, and fault types. Top-Level Exports from aquilia.i18n import ( Locale, parse_locale, normalize_locale, parse_accept_language, negotiate_locale, TranslationCatalog, MemoryCatalog, FileCatalog, SurpCatalog, NamespacedCatalog, MergedCatalog, PluralCategory, get_plural_rule, select_plural, MessageFormatter, format_message, format_number, format_currency, format_date, I18nConfig, I18nService, create_i18n_service, LazyString, lazy_t, lazy_tn, I18nMiddleware, ChainLocaleResolver, register_i18n_template_globals, I18nTemplateExtension, register_i18n_providers, I18nFault, MissingTranslationFault, ) Behavior Map • parse_locale validates and normalizes locale tags and may raise config-domain validation faults. • I18nService.t /tn can raise MissingTranslationFault when missing_key_strategy is set to raise. • I18nMiddleware writes resolved locale information into the request state, and cleans up ContextVars in a finally block. )

### Code Examples
```python
from aquilia.i18n import (
    Locale, parse_locale, normalize_locale, parse_accept_language, negotiate_locale,
    TranslationCatalog, MemoryCatalog, FileCatalog, SurpCatalog, NamespacedCatalog, MergedCatalog,
    PluralCategory, get_plural_rule, select_plural,
    MessageFormatter, format_message, format_number, format_currency, format_date,
    I18nConfig, I18nService, create_i18n_service,
    LazyString, lazy_t, lazy_tn,
    I18nMiddleware, ChainLocaleResolver,
    register_i18n_template_globals, I18nTemplateExtension,
    register_i18n_providers,
    I18nFault, MissingTranslationFault,
)
```



---

## i18n CLI Reference
**URL**: `https://tubox.cloud/docs/i18n/cli`

i18n / CLI i18n CLI Reference The aq i18n command group covers catalog initialization, validation, extraction, coverage measurement, and SURP compilation. Commands are registered in the CLI entrypoint and implemented in aquilia/cli/commands/i18n.py. Command Surface Command Purpose ))} aq i18n init aq i18n init --locales en,fr,de --directory locales --format json aq i18n init --locales en --directory translations --format yaml • Bootstraps locale folders and starter files such as locales/en/messages.json. • Skips files that already exist and only creates missing locale assets. aq i18n check and inspect aq i18n check aq i18n check --verbose aq i18n inspect • check validates enabled, default, fallback and resolver settings. • inspect prints effective configuration JSON using workspace-first load behavior. aq i18n extract aq i18n extract --source-dirs modules,templates --output locales/en/messages.json aq i18n extract --source-dirs modules,controllers --output locales/en/messages.json --no-merge Extraction scans translation calls in Python and template files, expands dotted keys to nested JSON, and merges with existing values. aq i18n coverage aq i18n coverage aq i18n coverage --verbose aq i18n compile aq i18n compile aq i18n compile --directory locales aq i18n compile --directory locales --output artifacts/locales )

### Code Examples
```python
aq i18n init --locales en,fr,de --directory locales --format json
aq i18n init --locales en --directory translations --format yaml
```

```python
aq i18n check
aq i18n check --verbose
aq i18n inspect
```

```python
aq i18n extract --source-dirs modules,templates --output locales/en/messages.json
aq i18n extract --source-dirs modules,controllers --output locales/en/messages.json --no-merge
```



---

## Edge Cases and Limitations
**URL**: `https://tubox.cloud/docs/i18n/edge-cases`

i18n / Edge Cases Edge Cases and Limitations This page captures behavior verified by tests plus practical implementation gaps that matter in production. Use it as a deployment hardening checklist. Validated Behaviors ))} Current Gaps and Caveats ))} Recommended Mitigations # 1) Keep resolver order explicit in production config Integration.i18n(resolver_order=["query", "cookie", "session", "header"]) # 2) Prefer request.state locale in controllers locale = request.state.get("locale", "en") # 3) Pair lazy context set/clear in custom middleware via try/finally from aquilia.i18n import set_lazy_context, clear_lazy_context set_lazy_context(service, locale) try: # Handle request pass finally: clear_lazy_context() )

### Code Examples
```python
# 1) Keep resolver order explicit in production config
Integration.i18n(resolver_order=["query", "cookie", "session", "header"])

# 2) Prefer request.state locale in controllers
locale = request.state.get("locale", "en")

# 3) Pair lazy context set/clear in custom middleware via try/finally
from aquilia.i18n import set_lazy_context, clear_lazy_context
set_lazy_context(service, locale)
try:
    # Handle request
    pass
finally:
    clear_lazy_context()
```



---

## Troubleshooting i18n
**URL**: `https://tubox.cloud/docs/i18n/troubleshooting`

i18n / Troubleshooting Troubleshooting i18n Symptom-driven diagnostics for the most common i18n runtime issues. Start with config visibility, then validate resolver behavior, then verify catalog content. Diagnostic Baseline aq i18n inspect aq i18n check aq i18n coverage --verbose @GET("/debug/i18n") async def debug_i18n(self, ctx: RequestCtx): state = ctx.request.state return Likely Causes ))} Recommended Fixes ))} ))} Operational Guardrails • Keep one canonical locale key naming convention across templates and controllers. • Run extraction and coverage checks in CI to prevent silent key drift. • Smoke test representative keys for each supported locale during startup validation. )

### Code Examples
```python
aq i18n inspect
aq i18n check
aq i18n coverage --verbose
```

```python
@GET("/debug/i18n")
async def debug_i18n(self, ctx: RequestCtx):
    state = ctx.request.state
    return {
        "has_i18n": "i18n" in state,
        "locale": state.get("locale"),
        "available_locales": state["i18n"].available_locales() if "i18n" in state else [],
    }
```



---

## WebSockets Overview
**URL**: `https://tubox.cloud/docs/websockets`

Advanced / WebSockets WebSockets Overview AquilaSockets provides production-grade WebSocket support featuring a declarative, decorator-driven syntax. Every connection is backed by its own request-scoped DI container, auth-first upgrade guards, structured message envelopes, event streaming, and horizontal scaling via message broker adapters. System Integration & Registration To activate WebSocket routing, a controller must be mounted in your module's manifest, which is in turn loaded by the workspace configuration. 1. Workspace Registration Register your module within the workspace builder in workspace.py: from aquilia.workspace import Workspace, Module workspace = ( Workspace("myapp") .runtime(port=8000) .module( Module("chat") .route_prefix("/chat") ) ) 2. Manifest Mounting Mount the socket controller class inside your module's manifest file in the socket_controllers parameter: from aquilia.manifest import AppManifest manifest = AppManifest( name="chat", version="1.0.0", controllers=[], socket_controllers=[ "modules.chat.controllers:RoomChatController", ], services=[ "modules.chat.services:ChatService" ] ) Subsystem Architecture The WebSocket module separates connection lifecycle, message codec parsing, security validation, and pub/sub distribution into distinct components: , , , , , ].map((item, i) => ( ))} Extended Controller Implementation WebSocket controllers are defined by inheriting from SocketController and decorating with @Socket : from aquilia.sockets import ( SocketController, Socket, OnConnect, OnDisconnect, Event, AckEvent, Subscribe, Connection, Schema ) from aquilia import Inject @Socket("/ws/chat/:room") class RoomChatController(SocketController): @Inject() def __init__(self, chat_service: ChatService): self.chat = chat_service @OnConnect async def handle_connect(self, conn: Connection): # Read parameters from ASGI path patterns room = conn.scope.path_params.get("room") await conn.join(room) # Inject user identity resolved from handshake auth user = conn.identity await conn.send_event("welcome", !" }) @Event("chat.message", schema=Schema( )) async def on_message(self, conn: Connection, payload: dict): room = conn.scope.path_params["room"] # Broadcast to all connections in the room await conn.broadcast(room, "chat.message", ) @AckEvent("user.typing") async def on_typing(self, conn: Connection, payload: dict): room = conn.scope.path_params["room"] await conn.broadcast(room, "user.typing", ) return # Returned directly to the sender as an ACK Core Capabilities DI-Scoped Handlers Every connection creates its own request-scoped dependency injection container. Scoped objects are automatically created, injected, and cleaned up when the client disconnects. Robust Handshake Security Authenticates connections via Authorization Bearer headers, query string tokens, or cookies, using HTTP guard logic before upgrading the connection to a WebSocket. Horizontal Scaling Pluggable broker adapters (such as RedisAdapter ) forward broadcast and room events across multiple servers seamlessly, ensuring instant pub/sub delivery. Cache Socket Controllers )

### Code Examples
```python
from aquilia.workspace import Workspace, Module

workspace = (
    Workspace("myapp")
    .runtime(port=8000)
    .module(
        Module("chat")
        .route_prefix("/chat")
    )
)
```

```python
from aquilia.manifest import AppManifest

manifest = AppManifest(
    name="chat",
    version="1.0.0",
    controllers=[],
    socket_controllers=[
        "modules.chat.controllers:RoomChatController",
    ],
    services=[
        "modules.chat.services:ChatService"
    ]
)
```

```python
from aquilia.sockets import (
    SocketController, Socket, OnConnect, OnDisconnect,
    Event, AckEvent, Subscribe, Connection, Schema
)
from aquilia import Inject

@Socket("/ws/chat/:room")
class RoomChatController(SocketController):

    @Inject()
    def __init__(self, chat_service: ChatService):
        self.chat = chat_service

    @OnConnect
    async def handle_connect(self, conn: Connection):
        # Read parameters from ASGI path patterns
        room = conn.scope.path_params.get("room")
        await conn.join(room)
        
        # Inject user identity resolved from handshake auth
        user = conn.identity
        await conn.send_event("welcome", {
            "msg": f"Hello {user.username if user else 'Guest'}!"
        })

    @Event("chat.message", schema=Schema({"text": str}))
    async def on_message(self, conn: Connection, payload: dict):
        room = conn.scope.path_params["room"]
        # Broadcast to all connections in the room
        await conn.broadcast(room, "chat.message", {
            "sender": conn.id,
            "text": payload["text"]
        })

    @AckEvent("user.typing")
    async def on_typing(self, conn: Connection, payload: dict):
        room = conn.scope.path_params["room"]
        await conn.broadcast(room, "user.typing", {"user": conn.id})
        return {"delivered": True}  # Returned directly to the sender as an ACK
```



---

## Socket Controllers
**URL**: `https://tubox.cloud/docs/websockets/controllers`

WebSockets / Socket Controllers Socket Controllers WebSocket handlers in Aquilia are declared inside classes inheriting from SocketController . Every incoming client connection gets a stateless controller instance bound to its own request-scoped DI container, letting you inject services, handle connection events, validate schemas, and stream responses. Extended Implementation Example The following controller demonstrates connection handshakes, pub/sub room subscriptions, validation schema boundaries, rate-limiting guards, and message acknowledgments in a single production-ready class: from aquilia.sockets import ( SocketController, Socket, OnConnect, OnDisconnect, Event, AckEvent, Subscribe, Unsubscribe, Guard, Connection, Schema ) from aquilia.di import Inject from typing import Annotated @Socket( path="/rooms/:room_id", allowed_origins=["https://myapp.com"], max_message_size=1024 * 1024, # 1MB compression=True ) class ChatRoomController(SocketController): def __init__(self, chat_service: Annotated[ChatService, Inject()]): self.chat = chat_service @OnConnect async def on_connect(self, conn: Connection): # Path parameter extraction room_id = conn.scope.path_params.get("room_id") # 1. Join connection to room await conn.join(room_id) # 2. Retrieve identity properties user = conn.identity username = user.username if user else "Anonymous" await conn.send_event("presence.join", ) @Subscribe("chat.history") async def on_subscribe(self, conn: Connection): room_id = conn.scope.path_params["room_id"] history = await self.chat.get_history(room_id) await conn.send_event("chat.history_dump", ) @Event("message.send", schema=Schema( )) async def on_new_message(self, conn: Connection, payload: dict): room_id = conn.scope.path_params["room_id"] # Save through dependency-injected service msg = await self.chat.save_message(room_id, conn.id, payload["text"]) # Broadcast to all connections in the room await conn.broadcast(room_id, "message.receive", msg.to_dict()) @AckEvent("typing.state") async def on_typing(self, conn: Connection, payload: dict): room_id = conn.scope.path_params["room_id"] # Broadcast to room excluding the current sender await conn.broadcast( room_id, "typing.state", , exclude_connection=conn.id ) # Return ACK status back to the sender client return @Unsubscribe("chat.history") async def on_unsubscribe(self, conn: Connection): pass @OnDisconnect async def on_disconnect(self, conn: Connection, reason: str | None = None): room_id = conn.scope.path_params.get("room_id") await conn.leave(room_id) await conn.broadcast(room_id, "presence.leave", ) Decorator Reference , )` }, closed connection. " f"Reason: . " f"Duration: s" ) # 3. Clean up cluster states await conn.leave("broadcast_lobby")` }, ), ack=False ) async def on_new_comment(self, conn: Connection, payload: dict): post_id = payload["post_id"] comment_text = payload["comment"] # Save payload to database... await self.save_comment(conn.identity.id, post_id, comment_text) # Broadcast updates to the room await conn.broadcast(f"post_ ", "comment.added", )` }, ) ) async def on_checkout(self, conn: Connection, payload: dict) -> dict: cart_id = payload["cart_id"] # Process order workflow... success, transaction_id = await self.order_service.checkout(cart_id) if not success: # Returned dict is automatically packed into ACK payload back to sender return return ` }, ) return # Join billing events channel room await conn.join("room:billing_alerts") await conn.send_event("subscribe.success", )` }, )` }, )` } ].map((item, i) => ( ))} Connection Object API Every controller method receives a Connection instance representing the active client session: )` }, , Closing: ") # Set and read arbitrary thread-safe connection local attributes state.custom_attrs["last_ping_at"] = datetime.utcnow() await conn.send_event("pong.state", )` }, , ) return await conn.send_event("profile.data", )` }, ) return # Read/Write directly to the ASGI Session transport counter = session.get("counter", 0) + 1 session["counter"] = counter await conn.send_event("session.count", )` }, )` }, , ack=True ) # Log msg_id to map incoming user acknowledgments later logger.info(f"Dispatched message with tracking ID: ")` }, } envelope # Sends a raw JSON array or dictionary directly down the socket await conn.send_json([ , ])` }, , " # Join connection to the channel await conn.join(room_name) # Broadcast join event to all other members in the room await conn.broadcast( room=room_name, event="user.joined", payload= , exclude_connection=conn.id )` }, " # Leave room channel await conn.leave(room_name) # Broadcast leave notification to remaining members await conn.broadcast( room=room_name, event="user.left", payload= )` }, ) # Triggers WS 1008 Policy Violation close event await conn.disconnect(reason="forced_termination", code=1008)` }, ].map((item, i) => ( ))} WebSocket Chunked Streaming AquilaSockets supports first-class streaming. If a handler returns an AsyncIterator or Iterator, the runtime will automatically consume it and stream chunks to the client: @Event("logs.stream") async def handle_logs_stream(self, conn: Connection, payload: dict) -> AsyncIterator[dict]: # Generator yielding chunks back to the client for i in range(10): await asyncio.sleep(0.5) yield "} # Handled by runtime: # Sends 'logs.stream.chunk' events carrying each dictionary. # Ends the stream by dispatching 'logs.stream.end'. Overview WebSocket Runtime )

### Code Examples
```python
from aquilia.sockets import (
    SocketController, Socket, OnConnect, OnDisconnect,
    Event, AckEvent, Subscribe, Unsubscribe, Guard,
    Connection, Schema
)
from aquilia.di import Inject
from typing import Annotated

@Socket(
    path="/rooms/:room_id",
    allowed_origins=["https://myapp.com"],
    max_message_size=1024 * 1024,  # 1MB
    compression=True
)
class ChatRoomController(SocketController):

    def __init__(self, chat_service: Annotated[ChatService, Inject()]):
        self.chat = chat_service

    @OnConnect
    async def on_connect(self, conn: Connection):
        # Path parameter extraction
        room_id = conn.scope.path_params.get("room_id")
        
        # 1. Join connection to room
        await conn.join(room_id)
        
        # 2. Retrieve identity properties
        user = conn.identity
        username = user.username if user else "Anonymous"
        
        await conn.send_event("presence.join", {
            "user_id": conn.id,
            "username": username
        })

    @Subscribe("chat.history")
    async def on_subscribe(self, conn: Connection):
        room_id = conn.scope.path_params["room_id"]
        history = await self.chat.get_history(room_id)
        await conn.send_event("chat.history_dump", {"messages": history})

    @Event("message.send", schema=Schema({"text": str}))
    async def on_new_message(self, conn: Connection, payload: dict):
        room_id = conn.scope.path_params["room_id"]
        # Save through dependency-injected service
        msg = await self.chat.save_message(room_id, conn.id, payload["text"])
        
        # Broadcast to all connections in the room
        await conn.broadcast(room_id, "message.receive", msg.to_dict())

    @AckEvent("typing.state")
    async def on_typing(self, conn: Connection, payload: dict):
        room_id = conn.scope.path_params["room_id"]
        # Broadcast to room excluding the current sender
        await conn.broadcast(
            room_id, 
            "typing.state", 
            {"user_id": conn.id, "is_typing": payload.get("typing", False)},
            exclude_connection=conn.id
        )
        # Return ACK status back to the sender client
        return {"status": "ok"}

    @Unsubscribe("chat.history")
    async def on_unsubscribe(self, conn: Connection):
        pass

    @OnDisconnect
    async def on_disconnect(self, conn: Connection, reason: str | None = None):
        room_id = conn.scope.path_params.get("room_id")
        await conn.leave(room_id)
        await conn.broadcast(room_id, "presence.leave", {"user_id": conn.id})
```

```python
@Event("logs.stream")
async def handle_logs_stream(self, conn: Connection, payload: dict) -> AsyncIterator[dict]:
    # Generator yielding chunks back to the client
    for i in range(10):
        await asyncio.sleep(0.5)
        yield {"index": i, "data": f"Log line {i}"}

# Handled by runtime:
# Sends 'logs.stream.chunk' events carrying each dictionary.
# Ends the stream by dispatching 'logs.stream.end'.
```



---

## WebSocket Runtime
**URL**: `https://tubox.cloud/docs/websockets/runtime`

WebSockets / Runtime WebSocket Runtime The AquilaSockets runtime manages connection lifecycles, upgrades ASGI HTTP connections to WebSockets, decodes incoming messages, runs auth guards, and coordinates pub/sub scaling. Handshake & Lifespan Cycle When a client connects to a SocketController route, the runtime coordinates the lifecycle through these phases: , , , ].map((item, i) => ( ))} Built-in Security Guards Guards inherit from the base SocketGuard protocol class and are applied via @Guard decorators. They can intercept either the initial HTTP handshake or individual incoming client messages. 1. HandshakeAuthGuard Authenticates and authorizes connections during the initial HTTP upgrade handshake phase. If the check fails, the connection is aborted immediately. from aquilia.sockets import Guard, HandshakeAuthGuard # Require a valid user identity that is flagged as an admin @Guard(HandshakeAuthGuard( require_identity=True, require_session=True, allowed_identity_types=["admin"] )) class AdminSocketController(SocketController): pass 2. OriginGuard Validates the upgrade request's origin header against a list of allowed endpoints to prevent Cross-Site WebSocket Hijacking (CSWSH) attacks. from aquilia.sockets import Guard, OriginGuard # Reject any requests originating from unrecognized domains @Guard(OriginGuard(allowed_origins=["https://myapp.com", "https://*.myapp.com"])) class SecureController(SocketController): pass 3. MessageAuthGuard Periodically re-authenticates the user token during the lifespan of the WebSocket connection, ensuring revoked tokens disconnect active users within the set interval. from aquilia.sockets import Guard, MessageAuthGuard # Re-authenticate the active token every 5 minutes (300 seconds) @Guard(MessageAuthGuard(check_interval=300)) class LongLivedController(SocketController): pass 4. RateLimitGuard Applies rate limit controls on a per-connection basis to prevent clients from flooding handlers with excessive message frequencies. from aquilia.sockets import Guard, RateLimitGuard, Event class MessageRateController(SocketController): # Limit message.send events to a maximum of 5 payloads per second @Event("message.send") @Guard(RateLimitGuard(messages_per_second=5)) async def on_send(self, conn, payload): pass Writing Custom Socket Guards To write a custom guard, subclass SocketGuard and implement check_handshake (ran once at upgrade) or check_message (ran on every incoming message event): from aquilia.sockets import SocketGuard, Connection, ConnectionScope, MessageEnvelope from aquilia.faults import WS_FORBIDDEN # Socket fault status code class RoomAccessGuard(SocketGuard): def __init__(self, role: str): self.role = role async def check_handshake(self, scope: ConnectionScope) -> None: # Check permissions early from request headers or path parameters room_id = scope.path_params.get("room_id") user = scope.identity if not user or not user.has_room_role(room_id, self.role): # Abort the upgrade phase immediately raise WS_FORBIDDEN("You do not have access to this room.") async def check_message(self, conn: Connection, envelope: MessageEnvelope) -> None: # Check permissions on specific incoming messages if envelope.event == "room.admin_action" and not conn.identity.is_staff: raise WS_FORBIDDEN("Staff only action.") Socket Controllers Adapters )

### Code Examples
```python
from aquilia.sockets import Guard, HandshakeAuthGuard

# Require a valid user identity that is flagged as an admin
@Guard(HandshakeAuthGuard(
    require_identity=True, 
    require_session=True, 
    allowed_identity_types=["admin"]
))
class AdminSocketController(SocketController):
    pass
```

```python
from aquilia.sockets import Guard, OriginGuard

# Reject any requests originating from unrecognized domains
@Guard(OriginGuard(allowed_origins=["https://myapp.com", "https://*.myapp.com"]))
class SecureController(SocketController):
    pass
```

```python
from aquilia.sockets import Guard, MessageAuthGuard

# Re-authenticate the active token every 5 minutes (300 seconds)
@Guard(MessageAuthGuard(check_interval=300))
class LongLivedController(SocketController):
    pass
```



---

## Scaling Adapters
**URL**: `https://tubox.cloud/docs/websockets/adapters`

WebSockets / Adapters Scaling Adapters Adapters route events, channel subscriptions, room memberships, and messages across your application processes. This pub/sub interface enables AquilaSockets to scale horizontally from a single node to multi-server clusters. The Adapter Base Class To write a custom adapter (e.g. for NATS or RabbitMQ), inherit from the base Adapter class and implement the following async signature interfaces: from aquilia.sockets import Adapter, MessageEnvelope class CustomAdapter(Adapter): async def initialize(self) -> None: """Establish client connections to external message brokers.""" pass async def shutdown(self) -> None: """Close connections and flush buffers during server teardown.""" pass async def publish(self, namespace: str, room: str, envelope: MessageEnvelope, exclude_connection: str | None = None) -> None: """Publish a message to all members subscribing to a room across clusters.""" pass async def broadcast(self, namespace: str, envelope: MessageEnvelope, exclude_connection: str | None = None) -> None: """Broadcast a message to all active connections inside a namespace.""" pass async def join_room(self, namespace: str, room: str, connection_id: str) -> None: """Register a connection ID as a member of a room.""" pass async def leave_room(self, namespace: str, room: str, connection_id: str) -> None: """Unregister a connection ID from a room.""" pass async def get_room_members(self, namespace: str, room: str) -> set[str]: """Fetch active connection IDs inside a room across nodes.""" return set() async def get_connection_count(self, namespace: str) -> int: """Fetch total client count within the namespace.""" return 0 InMemoryAdapter (Default) The default adapter manages connection states, room memberships, and broadcasts entirely inside the local application memory. It is optimized for single-instance applications, developer environments, and automated testing suites. from aquilia.sockets import AquilaSockets, InMemoryAdapter sockets = AquilaSockets( router=router, adapter=InMemoryAdapter() ) RedisAdapter (Production Scaling) The RedisAdapter uses Redis Pub/Sub channels to sync message delivery between server processes. Connection metadata and room rosters are maintained atomically inside Redis Sets and Sorted Sets: from aquilia.sockets import AquilaSockets, RedisAdapter adapter = RedisAdapter( url="redis://localhost:6379/0", channel_prefix="ws:", pool_size=15 ) sockets = AquilaSockets( router=router, adapter=adapter ) Implementing a Custom Adapter To integrate with other messaging brokers like NATS or RabbitMQ, inherit from Adapter: from aquilia.sockets import Adapter, MessageEnvelope class NatsWebSocketAdapter(Adapter): def __init__(self, nats_url: str): self.nats_url = nats_url self.nc = None async def initialize(self): import nats self.nc = await nats.connect(self.nats_url) async def publish(self, namespace: str, room: str, envelope: MessageEnvelope, exclude_connection: str | None = None): subject = f"ws. . " payload = self.codec.encode(envelope) await self.nc.publish(subject, payload) async def shutdown(self): if self.nc: await self.nc.close() WebSocket Runtime Templates )

### Code Examples
```python
from aquilia.sockets import Adapter, MessageEnvelope

class CustomAdapter(Adapter):

    async def initialize(self) -> None:
        """Establish client connections to external message brokers."""
        pass

    async def shutdown(self) -> None:
        """Close connections and flush buffers during server teardown."""
        pass

    async def publish(self, namespace: str, room: str, envelope: MessageEnvelope, exclude_connection: str | None = None) -> None:
        """Publish a message to all members subscribing to a room across clusters."""
        pass

    async def broadcast(self, namespace: str, envelope: MessageEnvelope, exclude_connection: str | None = None) -> None:
        """Broadcast a message to all active connections inside a namespace."""
        pass

    async def join_room(self, namespace: str, room: str, connection_id: str) -> None:
        """Register a connection ID as a member of a room."""
        pass

    async def leave_room(self, namespace: str, room: str, connection_id: str) -> None:
        """Unregister a connection ID from a room."""
        pass

    async def get_room_members(self, namespace: str, room: str) -> set[str]:
        """Fetch active connection IDs inside a room across nodes."""
        return set()

    async def get_connection_count(self, namespace: str) -> int:
        """Fetch total client count within the namespace."""
        return 0
```

```python
from aquilia.sockets import AquilaSockets, InMemoryAdapter

sockets = AquilaSockets(
    router=router,
    adapter=InMemoryAdapter()
)
```

```python
from aquilia.sockets import AquilaSockets, RedisAdapter

adapter = RedisAdapter(
    url="redis://localhost:6379/0",
    channel_prefix="ws:",
    pool_size=15
)

sockets = AquilaSockets(
    router=router,
    adapter=adapter
)
```



---

## Template Engine Overview
**URL**: `https://tubox.cloud/docs/templates`

Advanced / Templates Template Engine Overview AquilaTemplates is an async-native rendering engine built on top of Jinja2. It features sandboxed script execution, module-aware namespace loaders, precompiled bytecode caching, and auto-populated request/session contexts. System Integration & Registration Configure templates at the workspace level and organize directories within module structures. 1. Workspace Integration Register templates inside workspace.py using TemplatesIntegration : from aquilia.workspace import Workspace from aquilia.integrations import TemplatesIntegration workspace = ( Workspace("myapp") .integrate(TemplatesIntegration( search_paths=["templates", "shared_templates"], cache="memory", sandbox=True, sandbox_policy="strict" )) ) 2. Manifest Auto-Discovery & Layout By default, templates placed inside modules under the templates/ folder are auto-discovered. You can also customize search paths inside module.aq: } Engine Architecture , , , ].map((item, i) => ( ))} Rendering in Controllers Access the template system either through controller helper methods or by direct invocation of the injected TemplateEngine : from aquilia import Controller, Get, Inject from aquilia.templates import TemplateEngine class WebController(Controller): @Inject() def __init__(self, templates: TemplateEngine): self.templates = templates @Get("/") async def index(self, ctx): # 1. Convenient controller render helper (returns Response) return await self.render("index.html", , request_ctx=ctx) @Get("/profile") async def profile(self, ctx): # 2. Render directly to string via TemplateEngine html = await self.templates.render( "profile.html", , request_ctx=ctx ) return ctx.html(html) @Get("/dashboard") async def dashboard(self, ctx): # 3. Direct response generation via TemplateEngine return await self.templates.render_to_response( "dashboard.html", , status=200, request_ctx=ctx ) Auto-Injected Context Variables When rendering templates with request_ctx provided, the environment automatically attaches standard context helpers and objects: , , , , , , ].map((item, i) => ( ))} Adapters TemplateEngine )

### Code Examples
```python
from aquilia.workspace import Workspace
from aquilia.integrations import TemplatesIntegration

workspace = (
    Workspace("myapp")
    .integrate(TemplatesIntegration(
        search_paths=["templates", "shared_templates"],
        cache="memory",
        sandbox=True,
        sandbox_policy="strict"
    ))
)
```

```python
{
  "templates": {
    "enabled": true,
    "search_paths": [
      "./templates",
      "./custom_themes"
    ],
    "precompile": true,
    "cache": "surp"
  }
}
```

```python
from aquilia import Controller, Get, Inject
from aquilia.templates import TemplateEngine

class WebController(Controller):

    @Inject()
    def __init__(self, templates: TemplateEngine):
        self.templates = templates

    @Get("/")
    async def index(self, ctx):
        # 1. Convenient controller render helper (returns Response)
        return await self.render("index.html", {"title": "Home"}, request_ctx=ctx)

    @Get("/profile")
    async def profile(self, ctx):
        # 2. Render directly to string via TemplateEngine
        html = await self.templates.render(
            "profile.html", 
            {"user": ctx.identity}, 
            request_ctx=ctx
        )
        return ctx.html(html)

    @Get("/dashboard")
    async def dashboard(self, ctx):
        # 3. Direct response generation via TemplateEngine
        return await self.templates.render_to_response(
            "dashboard.html",
            {"stats": await get_stats()},
            status=200,
            request_ctx=ctx
        )
```



---

## TemplateEngine API
**URL**: `https://tubox.cloud/docs/templates/engine`

Templates / TemplateEngine TemplateEngine API The TemplateEngine class governs Jinja2 parsing environments, resolves namespaced sources, loads precompiled bytecode caches, and applies sandboxing rules. Method API Reference , request_ctx=ctx ) return html_content` }, ) return markup` }, , request_ctx=ctx ): yield chunk` }, , status=200, headers= , request_ctx=ctx )` }, , status=200, headers= , request_ctx=ctx )` }, ")` }, .html")` }, }).', code: `def register_formatting_filters(self): # Register custom filters dynamically into the template environment self.templates.register_filter( name="obfuscate_email", func=lambda val: val.split("@")[0][:3] + "***@" + val.split("@")[1] )` }, ") self.templates.register_global("check_feature_flag", lambda flag: self.flags.enabled(flag))` } ].map((item, i) => ( ))} Built-in Filters AquilaTemplates extends Jinja2 with a set of default data formatters. Here is how they are used inside templates: } Joined on: July 09, 2026 -->` }, } Total: $1,240.50 -->` }, } } You have 3 items -->` }, } Hello World -->` }, }; ` } ].map((item, i) => ( ))} Bytecode Caching Templates are compiled into python bytecode. Choose from two distinct caching behaviors: MemoryBytecodeCache Stores compiled abstract syntax tree nodes entirely inside RAM. Fast execution speeds, ideal for ephemeral container dynos and cloud functions. SurpBytecodeCache Compiles templates into a single compressed `.surp` archive. HMAC signatures verify the bytecode integrity on startup to prevent local file tampering. Overview Loaders )


---

## Template Loaders & Namespaces
**URL**: `https://tubox.cloud/docs/templates/loaders`

Templates / Loaders Template Loaders & Namespaces Loaders manage how template source strings are located and read. The TemplateLoader class resolves template files across multiple project search paths and modules. Namespace Resolution Formats The loader determines the physical path of a template based on the naming syntax used inside controller calls or template directives: , , , ].map((item, i) => ( ))} TemplateLoader Configuration Instantiate TemplateLoader with custom search paths and package mappings: from aquilia.templates import TemplateLoader loader = TemplateLoader( search_paths=["templates", "shared_templates"], package_loaders= , default_module="home" ) Manifest-Aware Loaders The system can auto-discover template folders by scanning project manifests (`module.aq` or `manifest.py`). Enable this using built-in discovery functions: from aquilia.templates.manifest_integration import ( discover_template_directories, create_manifest_aware_loader ) # 1. Discover all "templates" directories relative to current path discovered_dirs = discover_template_directories(scan_manifests=True) # 2. Generate a ready-to-use loader targeting all discovered paths manifest_loader = create_manifest_aware_loader(scan_manifests=True) TemplateManager The TemplateManager compiles template source code into bytecode files and runs automated linter audits to catch bugs prior to deployment: from aquilia.templates import TemplateManager manager = TemplateManager(engine=engine, loader=loader) # 1. Compile all templates to a .surp bytecode archive (Atomic write with HMAC signature) await manager.compile_all(output_path="artifacts/templates.surp") # 2. Run template linter (identifies syntax errors, undefined variables, disallowed filters) issues = await manager.lint_all(strict_undefined=True) for issue in issues: print(issue) # Output format: template.html:line:col: severity: msg [code] # 3. Retrieve a list of all template paths discovered by loader available_templates = loader.list_templates() TemplateEngine Security )

### Code Examples
```python
from aquilia.templates import TemplateLoader

loader = TemplateLoader(
    search_paths=["templates", "shared_templates"],
    package_loaders={"admin": "aquilia_admin"},
    default_module="home"
)
```

```python
from aquilia.templates.manifest_integration import (
    discover_template_directories, create_manifest_aware_loader
)

# 1. Discover all "templates" directories relative to current path
discovered_dirs = discover_template_directories(scan_manifests=True)

# 2. Generate a ready-to-use loader targeting all discovered paths
manifest_loader = create_manifest_aware_loader(scan_manifests=True)
```

```python
from aquilia.templates import TemplateManager

manager = TemplateManager(engine=engine, loader=loader)

# 1. Compile all templates to a .surp bytecode archive (Atomic write with HMAC signature)
await manager.compile_all(output_path="artifacts/templates.surp")

# 2. Run template linter (identifies syntax errors, undefined variables, disallowed filters)
issues = await manager.lint_all(strict_undefined=True)
for issue in issues:
    print(issue) # Output format: template.html:line:col: severity: msg [code]

# 3. Retrieve a list of all template paths discovered by loader
available_templates = loader.list_templates()
```



---

## Template Security Sandbox
**URL**: `https://tubox.cloud/docs/templates/security`

Templates / Security Template Security Sandbox AquilaTemplates enforces restricted sandboxing by default. The TemplateSandbox class and its accompanying SandboxPolicy prevent templates from executing arbitrary Python scripts or calling unauthorized object methods. SandboxPolicy Options Define sandbox policies by initializing SandboxPolicy with custom whitelists, or use the pre-configured classmethod presets: from aquilia.templates import SandboxPolicy, TemplateSandbox # 1. Custom Whitelist Security Policy policy = SandboxPolicy( allow_unsafe_filters=False, allow_unsafe_tests=False, allow_unsafe_globals=False, allowed_filters= , allowed_tests= , allowed_globals= , autoescape=True, autoescape_extensions=["html", "htm", "xml", "xhtml"], max_recursion_depth=50 ) sandbox = TemplateSandbox(policy=policy, immutable=True) Standard Policy Presets SandboxPolicy.strict() (Default) Blocks all unsafe actions, filters, tests, and globals. Allows only whitelisted operations. Perfect for production environments rendering user-submitted templates. SandboxPolicy.permissive() Expands the allowed filters and tests list (adding operations like tojson and xmlattr) to aid in diagnostic reporting and development-level debugging. Sandbox Whitelist References The following standard features are whitelisted out-of-the-box by the default strict policy: , , ].map((item, i) => ( ))} Auto-Escaping & XSS Prevention To safeguard templates against Cross-Site Scripting (XSS), the environment automatically escapes standard variables matching the autoescape_extensions set: } } } Loaders Mail )

### Code Examples
```python
from aquilia.templates import SandboxPolicy, TemplateSandbox

# 1. Custom Whitelist Security Policy
policy = SandboxPolicy(
    allow_unsafe_filters=False,
    allow_unsafe_tests=False,
    allow_unsafe_globals=False,
    allowed_filters={"abs", "capitalize", "escape", "length"},
    allowed_tests={"defined", "undefined", "even", "odd"},
    allowed_globals={"range", "namespace", "csrf_token"},
    autoescape=True,
    autoescape_extensions=["html", "htm", "xml", "xhtml"],
    max_recursion_depth=50
)

sandbox = TemplateSandbox(policy=policy, immutable=True)
```

```python
{# 1. Automatic Escaping (converts HTML characters to entities) #}
<p>{{ user.biography }}</p>

{# 2. Explicit Safe Escape (ONLY use for verified database outputs) #}
<p>{{ user.raw_html_bio | safe }}</p>

{# 3. Inline HTML Sanitizer Filter #}
<p>{{ user.untrusted_input | sanitize_html }}
```



---

## Mail System Overview
**URL**: `https://tubox.cloud/docs/mail`

Advanced / Mail Mail System Overview AquilaMail is a production-ready mail dispatching subsystem featuring pluggable providers (SMTP, AWS SES, SendGrid), DKIM signing, automatic rate limiting, retry backoffs, and an integrated testing outbox. System Integration & Registration To enable email operations, declare the Mail integration at the workspace level, configure templates, and inject the service into your module endpoints. 1. Workspace Integration Register Mail in workspace.py using MailIntegration : from aquilia.workspace import Workspace from aquilia.integrations import MailIntegration, SmtpProvider, MailAuth workspace = ( Workspace("myapp") .integrate(MailIntegration( default_from="noreply@myapp.com", subject_prefix="[MyApp] ", auth=MailAuth.plain("smtp_user", password_env="SMTP_PASSWORD"), providers=[ SmtpProvider(host="smtp.sendgrid.net", port=587, use_tls=True) ], rate_limit_global=1000, dkim_enabled=False )) ) 2. Injecting Mail Service in Modules Inject MailService directly into controllers or services to access the sending APIs: from aquilia import Controller, Post, Inject from aquilia.mail import MailService, TemplateMessage class AuthController(Controller): prefix = "/auth" @Inject() def __init__(self, mail: MailService): self.mail = mail @Post("/notify") async def notify(self, ctx): msg = TemplateMessage( template="alert.aqt", context= , subject="Security Alert", to=[ctx.identity.email] ) await msg.asend() return ctx.json( ) Core Mail Architectures , , , ].map((item, i) => ( ))} Testing Outbox Assertions During testing, the mail system captures outbound emails into an in-memory outbox list rather than dispatching them to external SMTP servers: from aquilia.testing import AquiliaTestCase, MailTestMixin class RegistrationTestCase(AquiliaTestCase, MailTestMixin): async def test_registration_welcomes(self): await self.client.post("/auth/register") # Verify that exactly one email was sent self.assert_mail_sent(count=1) # Pull the message from outbox and assert properties sent_msg = self.get_sent_mail()[0] assert sent_msg.to == "user@example.com" assert "Welcome!" in sent_msg.subject Security MailService )

### Code Examples
```python
from aquilia.workspace import Workspace
from aquilia.integrations import MailIntegration, SmtpProvider, MailAuth

workspace = (
    Workspace("myapp")
    .integrate(MailIntegration(
        default_from="noreply@myapp.com",
        subject_prefix="[MyApp] ",
        auth=MailAuth.plain("smtp_user", password_env="SMTP_PASSWORD"),
        providers=[
            SmtpProvider(host="smtp.sendgrid.net", port=587, use_tls=True)
        ],
        rate_limit_global=1000,
        dkim_enabled=False
    ))
)
```

```python
from aquilia import Controller, Post, Inject
from aquilia.mail import MailService, TemplateMessage

class AuthController(Controller):
    prefix = "/auth"

    @Inject()
    def __init__(self, mail: MailService):
        self.mail = mail

    @Post("/notify")
    async def notify(self, ctx):
        msg = TemplateMessage(
            template="alert.aqt",
            context={"user": ctx.identity},
            subject="Security Alert",
            to=[ctx.identity.email]
        )
        await msg.asend()
        return ctx.json({"sent": True})
```

```python
from aquilia.testing import AquiliaTestCase, MailTestMixin

class RegistrationTestCase(AquiliaTestCase, MailTestMixin):

    async def test_registration_welcomes(self):
        await self.client.post("/auth/register")
        
        # Verify that exactly one email was sent
        self.assert_mail_sent(count=1)
        
        # Pull the message from outbox and assert properties
        sent_msg = self.get_sent_mail()[0]
        assert sent_msg.to == "user@example.com"
        assert "Welcome!" in sent_msg.subject
```



---

## MailService API
**URL**: `https://tubox.cloud/docs/mail/service`

Mail / MailService MailService API The MailService orchestrates email compilation, DKIM signing, rate limiting, and provider dispatch. Learn how to build messages, attach files, set custom headers, and handle errors. EmailMessage API Usages Construct plain-text or HTML-alternative emails using EmailMessage and EmailMultiAlternatives: from aquilia.mail import EmailMessage, EmailMultiAlternatives, Attachment # 1. Simple Plain Text Email msg = EmailMessage( subject="Invoice #2041", body="Your invoice is attached.", from_email="billing@myapp.com", to=["client@example.com"], cc=["accountant@myapp.com"], priority=80, # High priority (default is 50) headers= ) # Add attachment msg.attach(Attachment(filename="invoice.pdf", content=b"...pdf_bytes...", content_type="application/pdf")) await msg.asend() # 2. HTML Alternative Email html_msg = EmailMultiAlternatives( subject="Monthly Newsletter", body="Read the newsletter online at https://myapp.com/newsletter", from_email="newsletter@myapp.com", to=["user@example.com"] ) # Attach the HTML body alternative html_msg.attach_alternative(" Our Monthly Updates Here is the news... ", content_type="text/html") await html_msg.asend() The MailEnvelope Dataclass When messages are processed, they are converted into an immutable MailEnvelope that represents the delivery unit of work: from dataclasses import dataclass, field from datetime import datetime from typing import Any @dataclass class MailEnvelope: id: str # Unique UUID tracking string created_at: datetime # Creation timestamp # Queue Priority priority: int = 50 # Priority rating (0-100) # Addressing from_email: str = "" # Normalized sender address to: list[str] = field(default_factory=list) cc: list[str] = field(default_factory=list) bcc: list[str] = field(default_factory=list) reply_to: str | None = None # Content subject: str = "" # Pre-interpolated subject line body_text: str = "" # Plain text representation body_html: str | None = None # HTML alternative body headers: dict[str, str] = field(default_factory=dict) # Attachments attachments: list[Attachment] = field(default_factory=list) # Idempotency & Verification idempotency_key: str | None = None digest: str = "" # SHA-256 checksum hash of the envelope Mail Fault Handling The mail subsystem raises structured exceptions based on the failure domain: , , , , ].map((f, i) => ( ))} from aquilia.mail import TemplateMessage from aquilia.faults import MailSendFault, MailValidationFault try: msg = TemplateMessage( template="welcome.aqt", subject="Welcome!", to=["invalid-email-format"] ) await msg.asend() except MailValidationFault as e: print(f"Validation failed: ") except MailSendFault as e: print(f"Network delivery failed: ") Overview Providers )

### Code Examples
```python
from aquilia.mail import EmailMessage, EmailMultiAlternatives, Attachment

# 1. Simple Plain Text Email
msg = EmailMessage(
    subject="Invoice #2041",
    body="Your invoice is attached.",
    from_email="billing@myapp.com",
    to=["client@example.com"],
    cc=["accountant@myapp.com"],
    priority=80,  # High priority (default is 50)
    headers={"X-Invoice-ID": "2041"}
)

# Add attachment
msg.attach(Attachment(filename="invoice.pdf", content=b"...pdf_bytes...", content_type="application/pdf"))
await msg.asend()

# 2. HTML Alternative Email
html_msg = EmailMultiAlternatives(
    subject="Monthly Newsletter",
    body="Read the newsletter online at https://myapp.com/newsletter",
    from_email="newsletter@myapp.com",
    to=["user@example.com"]
)
# Attach the HTML body alternative
html_msg.attach_alternative("<h1>Our Monthly Updates</h1><p>Here is the news...</p>", content_type="text/html")
await html_msg.asend()
```

```python
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any

@dataclass
class MailEnvelope:
    id: str                       # Unique UUID tracking string
    created_at: datetime          # Creation timestamp

    # Queue Priority
    priority: int = 50            # Priority rating (0-100)

    # Addressing
    from_email: str = ""          # Normalized sender address
    to: list[str] = field(default_factory=list)
    cc: list[str] = field(default_factory=list)
    bcc: list[str] = field(default_factory=list)
    reply_to: str | None = None

    # Content
    subject: str = ""             # Pre-interpolated subject line
    body_text: str = ""           # Plain text representation
    body_html: str | None = None  # HTML alternative body
    headers: dict[str, str] = field(default_factory=dict)

    # Attachments
    attachments: list[Attachment] = field(default_factory=list)

    # Idempotency & Verification
    idempotency_key: str | None = None
    digest: str = ""              # SHA-256 checksum hash of the envelope
```

```python
from aquilia.mail import TemplateMessage
from aquilia.faults import MailSendFault, MailValidationFault

try:
    msg = TemplateMessage(
        template="welcome.aqt",
        subject="Welcome!",
        to=["invalid-email-format"]
    )
    await msg.asend()
except MailValidationFault as e:
    print(f"Validation failed: {e.message}")
except MailSendFault as e:
    print(f"Network delivery failed: {e.message}")
```



---

## Mail Providers & Backends
**URL**: `https://tubox.cloud/docs/mail/providers`

Mail / Providers Mail Providers & Backends All email backends implement the standard IMailProvider protocol, allowing you to swap backends between local files, stdout consoles, and cloud providers (SMTP, SES, SendGrid) without changing your application code. Pluggable Backends Comparison , , , , ].map((item, i) => ( deps: ))} IMailProvider Custom Implementation To write a custom provider (e.g., Postmark API), implement the IMailProvider interface using native `aquilia.http` async clients, error handling structures, and status code maps: from aquilia.http import AsyncHTTPClient from aquilia.mail.providers import IMailProvider, ProviderResult, ProviderResultStatus from aquilia.mail import MailEnvelope class PostmarkMailProvider(IMailProvider): name = "postmark" supports_batching = False max_batch_size = 1 def __init__(self, api_token: str): self.api_token = api_token self.client = None async def initialize(self) -> None: # Open a persistent connection pool with server credentials self.client = AsyncHTTPClient( headers= , timeout=10.0 ) async def send(self, envelope: MailEnvelope) -> ProviderResult: payload = try: response = await self.client.post("https://api.postmarkapp.com/email", json=payload) if response.status_code == 200: data = response.json() return ProviderResult( status=ProviderResultStatus.SUCCESS, provider_message_id=data.get("MessageID") ) elif response.status_code == 422: # Permanent failure (e.g. invalid recipient address format) return ProviderResult( status=ProviderResultStatus.PERMANENT_FAILURE, error_message=response.text ) elif response.status_code == 429: # Rate limited, request retry backoff duration return ProviderResult( status=ProviderResultStatus.RATE_LIMITED, retry_after=float(response.headers.get("Retry-After", 60)) ) else: return ProviderResult( status=ProviderResultStatus.TRANSIENT_FAILURE, error_message=f"HTTP Error : " ) except Exception as e: # Handle socket/timeout exceptions as transient retry attempts return ProviderResult( status=ProviderResultStatus.TRANSIENT_FAILURE, error_message=str(e) ) async def health_check(self) -> bool: try: res = await self.client.get("https://status.postmarkapp.com/api/v2/status.json") return res.status_code == 200 except Exception: return False async def shutdown(self) -> None: if self.client: await self.client.aclose() Provider Configurations Configure individual providers as list parameters inside the typed MailIntegration : from aquilia.integrations import ( MailIntegration, SmtpProvider, SesProvider, SendGridProvider ) workspace.integrate(MailIntegration( providers=[ # 1. Standard SMTP Server SmtpProvider( host="smtp.gmail.com", port=587, use_tls=True, timeout=15 ), # 2. Amazon SES SesProvider( region="us-east-1", aws_access_key_id="AKIA...", aws_secret_access_key="secret" ), # 3. SendGrid SendGridProvider( api_key="SG.xxx" ) ] )) MailProviderRegistry & Auto-Discovery The mail subsystem leverages Aquilia's PackageScanner to auto-discover provider classes. Register custom provider packages to make them auto-wireable: from aquilia.mail.di_providers import MailProviderRegistry registry = MailProviderRegistry() # 1. Register custom package to scan for IMailProvider classes registry.add_scan_package("myapp.mail_providers") # 2. Discover classes and get custom mapping discovered_types = registry.discover() # Result: MailService Mail Templates )

### Code Examples
```python
from aquilia.http import AsyncHTTPClient
from aquilia.mail.providers import IMailProvider, ProviderResult, ProviderResultStatus
from aquilia.mail import MailEnvelope

class PostmarkMailProvider(IMailProvider):
    name = "postmark"
    supports_batching = False
    max_batch_size = 1

    def __init__(self, api_token: str):
        self.api_token = api_token
        self.client = None

    async def initialize(self) -> None:
        # Open a persistent connection pool with server credentials
        self.client = AsyncHTTPClient(
            headers={
                "Accept": "application/json",
                "Content-Type": "application/json",
                "X-Postmark-Server-Token": self.api_token
            },
            timeout=10.0
        )

    async def send(self, envelope: MailEnvelope) -> ProviderResult:
        payload = {
            "From": envelope.from_email,
            "To": ",".join(envelope.to),
            "Subject": envelope.subject,
            "HtmlBody": envelope.body_html,
            "TextBody": envelope.body_text
        }
        try:
            response = await self.client.post("https://api.postmarkapp.com/email", json=payload)
            
            if response.status_code == 200:
                data = response.json()
                return ProviderResult(
                    status=ProviderResultStatus.SUCCESS,
                    provider_message_id=data.get("MessageID")
                )
            elif response.status_code == 422:
                # Permanent failure (e.g. invalid recipient address format)
                return ProviderResult(
                    status=ProviderResultStatus.PERMANENT_FAILURE,
                    error_message=response.text
                )
            elif response.status_code == 429:
                # Rate limited, request retry backoff duration
                return ProviderResult(
                    status=ProviderResultStatus.RATE_LIMITED,
                    retry_after=float(response.headers.get("Retry-After", 60))
                )
            else:
                return ProviderResult(
                    status=ProviderResultStatus.TRANSIENT_FAILURE,
                    error_message=f"HTTP Error {response.status_code}: {response.text}"
                )
        except Exception as e:
            # Handle socket/timeout exceptions as transient retry attempts
            return ProviderResult(
                status=ProviderResultStatus.TRANSIENT_FAILURE, 
                error_message=str(e)
            )

    async def health_check(self) -> bool:
        try:
            res = await self.client.get("https://status.postmarkapp.com/api/v2/status.json")
            return res.status_code == 200
        except Exception:
            return False

    async def shutdown(self) -> None:
        if self.client:
            await self.client.aclose()
```

```python
from aquilia.integrations import (
    MailIntegration, SmtpProvider, SesProvider, SendGridProvider
)

workspace.integrate(MailIntegration(
    providers=[
        # 1. Standard SMTP Server
        SmtpProvider(
            host="smtp.gmail.com", port=587, 
            use_tls=True, timeout=15
        ),
        # 2. Amazon SES
        SesProvider(
            region="us-east-1",
            aws_access_key_id="AKIA...",
            aws_secret_access_key="secret"
        ),
        # 3. SendGrid
        SendGridProvider(
            api_key="SG.xxx"
        )
    ]
))
```

```python
from aquilia.mail.di_providers import MailProviderRegistry

registry = MailProviderRegistry()

# 1. Register custom package to scan for IMailProvider classes
registry.add_scan_package("myapp.mail_providers")

# 2. Discover classes and get custom mapping
discovered_types = registry.discover()
# Result: {"smtp": SMTPProvider, "ses": SESProvider, "custom_http": CustomHttpProvider}
```



---

## Aquilia Template Syntax (ATS)
**URL**: `https://tubox.cloud/docs/mail/templates`

Mail / Templates Aquilia Template Syntax (ATS) AquilaMail templates utilize the Aquilia Template Syntax (ATS). ATS provides a simple expression engine designed to prevent code-injection vulnerabilities inside email bodies. ATS Syntax Reference & Complete Example The following example compiles user profiles, loops through purchases, formats localized currency, and structures blocks inside a single transaction receipt template: [[% extends "layouts/base.aqt" %]] [[% block body %]] Hi, >! Thank you for shopping at >. Your order # > has cleared. Your Ordered Items: [[% for item in order.items %]] > (Qty: >) - > [[% endfor %]] [[% if order.discount_amount > 0 %]] Promo applied: - > [[% else %]] No promotional codes applied. [[% endif %]] [[% endblock %]] ATS Syntax Rules , , , , ].map((item, i) => ( ))} Using TemplateMessage Instantiate a TemplateMessage class with the template file path and context payload. Subject lines can also contain inline ATS expressions: from aquilia.mail import TemplateMessage msg = TemplateMessage( template="order_receipt.aqt", context= }, "total": 129.99, "discount_amount": 15.00, "items": [ ] }, "brand_name": "Aquilia Inc" }, subject="Your Receipt for > from >!", to=["asha@example.com"] ) # Template renders at envelope compile time. HTML and text alternative are generated. await msg.asend() Providers Developer Guide )

### Code Examples
```python
[[% extends "layouts/base.aqt" %]]

[[% block body %]]
  <!-- 1. Dotted variable resolutions with title casing -->
  <h2>Hi, << order.customer.profile.name | title >>!</h2>
  
  <!-- 2. Global variable bindings and formatting filters -->
  <p>Thank you for shopping at << brand_name | upper >>. Your order #<< order.number >> has cleared.</p>
  
  <!-- 3. Loop iteration over transaction collections -->
  <h3>Your Ordered Items:</h3>
  <ul>
    [[% for item in order.items %]]
      <li><< item.title >> (Qty: << item.qty >>) - << item.subtotal | format_currency("USD") >></li>
    [[% endfor %]]
  </ul>

  <!-- 4. Control-flow conditional blocks -->
  [[% if order.discount_amount > 0 %]]
    <p style="color: #22c55e;">Promo applied: -<< order.discount_amount | format_currency("USD") >></p>
  [[% else %]]
    <p style="color: #999;">No promotional codes applied.</p>
  [[% endif %]]
[[% endblock %]]
```

```python
from aquilia.mail import TemplateMessage

msg = TemplateMessage(
    template="order_receipt.aqt",
    context={
        "order": {
            "number": "TX-104",
            "customer": {"profile": {"name": "asha"}},
            "total": 129.99,
            "discount_amount": 15.00,
            "items": [
                {"title": "Aquilia Server License", "qty": 1, "subtotal": 129.99}
            ]
        },
        "brand_name": "Aquilia Inc"
    },
    subject="Your Receipt for << order.number >> from << brand_name >>!",
    to=["asha@example.com"]
)

# Template renders at envelope compile time. HTML and text alternative are generated.
await msg.asend()
```



---

## CLI — The aq Command
**URL**: `https://tubox.cloud/docs/cli`

Tooling / CLI CLI — The aq Command Aquilate (aq) is Aquilia's native command-line tool. It manages the entire application lifecycle—from workspace bootstrap and module generation to static validation, artifact compilation, database migration, and Docker/Kubernetes deployment configurations. Philosophy , , , ].map((item, i) => ( ))} Global CLI Options These flags can be specified on the root aq command to control logging and output formatting: Flag Description ))} Documentation Sections , , , , , , , ].map((sec, i) => ( → ))} Admin Setup Core Commands )


---

## CLI Commands
**URL**: `https://tubox.cloud/docs/cli/commands`

CLI / Commands CLI Commands The aq command-line tool provides project scaffolding, development server, module management, migration, and inspection utilities. Command Reference , , , , , , , , , , ].map((c, i) => ( ))} )


---

## Code Scaffolding & Generators
**URL**: `https://tubox.cloud/docs/cli/generators`

CLI / Generators Code Scaffolding & Generators Scaffolding utilities automatically structure workspaces, create new isolation modules, and wire up controllers from templates, reducing boilerplate code. Workspace Generator The aq init workspace command bootstraps a standardized project layout. It generates configurations, helper scripts, and base files: aq init workspace my_project --template=api Scaffold Output Structure my_project/ ├── workspace.py # Central workspace definition & configuration ├── starter.py # Landing controller welcome handler ├── requirements.txt # Project python dependencies ├── pyproject.toml # Packaging metadata ├── modules/ # Composable modules folder └── artifacts/ # Compiled route & DI schema bundles Module Scaffolding The aq add module command creates self-contained directories under modules/, appending the module configuration details automatically: aq add module billing --depends-on=users --route-prefix=/v1/billing Scaffold Output Structure modules/billing/ ├── __init__.py ├── manifest.py # Module service & controller registry manifest ├── controllers.py # Controller implementations ├── models.py # Database ORM models ├── schemas.py # Input validation contracts ├── services.py # Business service providers └── tests/ # Module test suites Controller Generator The aq generate controller command scaffolds new controller class files containing routing endpoint templates, status code returns, and lifecycle hooks: # Scaffolds CRUD endpoints for User resource aq generate controller Users --resource=User --with-lifecycle # Scaffolds simple controller aq generate controller Health --simple Scaffolding Options Option Description ))} )

### Code Examples
```python
# Scaffolds CRUD endpoints for User resource
aq generate controller Users --resource=User --with-lifecycle

# Scaffolds simple controller
aq generate controller Health --simple
```



---

## Core Commands
**URL**: `https://tubox.cloud/docs/cli/core`

CLI / Core Commands Core Commands Core lifecycle commands handle workspace bootstrap, module configurations, manifest validations, asset compilation, and server execution. aq init workspace Creates a new workspace structure. Generates the base workspace.py, the entrypoint module, and configuration folders. # Initialize standard API project aq init workspace billing-api --template=api # Initialize minimal workspace without examples aq init workspace core-service --minimal --yes Options Option Description ))} aq add module Generates a new self-contained module directory inside modules/, creating a default manifest.py, controller, models, and tests files. # Standard module scaffold aq add module auth # Custom route prefix and module dependency declarations aq add module payments --depends-on=users --depends-on=auth --route-prefix=/v2/pay Options Option Description ))} aq validate Parses workspace manifests statically, checking that dependency graphs are clear of cycles and routes do not overlap. # Validate entire workspace aq validate # Run validation and output details in JSON format aq validate --strict --json aq compile Compiles modular controllers, routers, contracts, and translations into a compiled directory of static `.surp` files. This is recommended before deploying to production. # Run compilation aq compile # Watch the workspace for edits and automatically recompile files aq compile --watch --output=dist/ aq run Starts the development server. By default, it auto-detects ports from workspace.py, enabling hot reloading. # Start server on local defaults aq run # Bind custom host/port and disable pre-flight checks aq run --port=8080 --host=0.0.0.0 --skip-checks Options Option Description ))} aq serve Starts the production ASGI server. Recommended to wrap in Gunicorn using Uvicorn worker threads to manage concurrency. # Simple serve aq serve # Production gunicorn setup with 4 workers and custom bindings aq serve --use-gunicorn --workers=4 --bind=127.0.0.1:9000 --timeout=60 aq manifest update Synchronizes a module manifest by searching the folder structure for untracked controller classes or model definitions. # Sync payments module manifest aq manifest update payments # Perform dry-run sync check (useful in CI scripts) aq manifest update orders --check aq doctor Performs deep diagnostics on your active workspace setup. It validates imports, database adapters, cache connections, and environment files, reporting details in clean stdout or JSON format. # Run diagnostic check aq doctor # Export diagnostic logs as JSON aq doctor --json )

### Code Examples
```python
# Initialize standard API project
aq init workspace billing-api --template=api

# Initialize minimal workspace without examples
aq init workspace core-service --minimal --yes
```

```python
# Standard module scaffold
aq add module auth

# Custom route prefix and module dependency declarations
aq add module payments --depends-on=users --depends-on=auth --route-prefix=/v2/pay
```

```python
# Validate entire workspace
aq validate

# Run validation and output details in JSON format
aq validate --strict --json
```



---

## Database Commands
**URL**: `https://tubox.cloud/docs/cli/database`

CLI / Database Database Commands The aq db command group manages migrations, introspects tables, dumps schemas, and runs database shells. aq db makemigrations Analyzes your model classes in modules and diffs them against migration history to generate a new migration file. Diffs are compiled using the Aquilia DSL. # Generate migrations for all modules aq db makemigrations # Generate migrations only for the users module aq db makemigrations --app=users # Fall back to legacy SQL migrations instead of DSL aq db makemigrations --no-dsl Options Option Description ))} aq db migrate Executes pending migration files, applying changes to database schemas safely. # Apply all pending migrations aq db migrate # View execution plan without altering schemas aq db migrate --plan # Target a specific migration version (rolls back if version is in the past) aq db migrate --target=0004_add_profile_indexing Options Option Description ))} aq db showmigrations Displays all detected migration files, listing them sequentially with a checked or unchecked status indicator (e.g. [X] or [ ]) depending on whether they have been applied. aq db showmigrations aq db sqlmigrate Prints the raw SQL DDL queries compiled for a specific migration target name. Extremely helpful for review processes or manual SQL schemas approval. # Print SQL statements for migration 0002 aq db sqlmigrate 0002_create_user_table aq db dump Dumps model schemas into structured formats. # Dump DDL schema output as SQL aq db dump --emit=sql --output-dir=deploy/schema/ aq db inspectdb Introspects an existing database and prints auto-generated Python model code representing the tables. Helps with migrating legacy databases. # Introspect legacy database tables aq db inspectdb --database-url="postgresql://user:pass@localhost/legacy" aq db shell Launches an interactive, async Python REPL with the database connection and module model classes pre-loaded, facilitating quick queries. aq db shell aq db status Displays statistics on database connection states, including tables, columns, indexes, and row counts. aq db status )

### Code Examples
```python
# Generate migrations for all modules
aq db makemigrations

# Generate migrations only for the users module
aq db makemigrations --app=users

# Fall back to legacy SQL migrations instead of DSL
aq db makemigrations --no-dsl
```

```python
# Apply all pending migrations
aq db migrate

# View execution plan without altering schemas
aq db migrate --plan

# Target a specific migration version (rolls back if version is in the past)
aq db migrate --target=0004_add_profile_indexing
```

```python
# Print SQL statements for migration 0002
aq db sqlmigrate 0002_create_user_table
```



---

## Inspection & Discovery
**URL**: `https://tubox.cloud/docs/cli/inspection`

CLI / Inspection Inspection & Discovery The aq inspect and aq discover command suites inspect routing, DI dependencies, configuration values, and module loading without spinning up a live server. aq inspect routes Displays all routes registered in the application, showing HTTP verbs, URL templates, and target controller methods. aq inspect routes aq inspect di Prints the compiled Dependency Injection (DI) registry tree, showcasing registered classes, factory tokens, scopes, and active provider locations. aq inspect di aq inspect modules Lists loaded modules alongside active dependencies, import permissions, exports, and manifest configurations. aq inspect modules aq inspect faults Dumps all declared fault categories and domains, detailing security overrides and default HTTP status codes. aq inspect faults aq inspect config Renders the fully resolved application configuration, merging values from workspace.py, active environment variables, and dot-env files. aq inspect config aq discover Scans the workspace modules directory for new controllers, models, or tasks that are not yet registered in manifests. # List all untracked modules and handlers aq discover # Sync discovered components into active manifests automatically aq discover --sync # Sync dry-run to preview changes aq discover --sync --dry-run Options Option Description ))} aq analytics Provides static discovery analysis metrics, listing circular dependencies, registration bottlenecks, and manifest health scores. aq analytics )

### Code Examples
```python
# List all untracked modules and handlers
aq discover

# Sync discovered components into active manifests automatically
aq discover --sync

# Sync dry-run to preview changes
aq discover --sync --dry-run
```



---

## WebSocket Commands
**URL**: `https://tubox.cloud/docs/cli/websockets`

CLI / WebSocket Commands WebSocket Commands The aq ws command group provides administrative tools to inspect active WebSocket controllers, broadcast realtime events, compile client SDK code, purge rooms, and disconnect clients. aq ws inspect Dumps the compiled SocketController routing table and message channels compiled within your ws.surp artifacts bundle. aq ws inspect --artifacts-dir=artifacts aq ws broadcast Sends a payload event message to a namespace, room, or specific connection ID using the registered WebSocket adapter backend (e.g. Redis). # Broadcast chat event to general room aq ws broadcast --namespace=/chat --room=general --event=new_message --payload=' ' Options Option Description ))} aq ws gen-client Compiles compiled WebSocket SocketControllers and generates a fully typed TypeScript client SDK. # Compile TypeScript websocket client SDK aq ws gen-client --out=frontend/src/sdk --lang=ts aq ws purge-room Purges a room state from the adapter, forcing all currently connected client members of that room to disconnect. aq ws purge-room --namespace=/chat --room=general aq ws kick Forces the disconnection of a specific connection ID by submitting a kick command to the WebSocket adapter. aq ws kick --conn=client-connection-id-123 --reason="Admin maintenance" )

### Code Examples
```python
# Broadcast chat event to general room
aq ws broadcast --namespace=/chat --room=general --event=new_message --payload='{"msg":"hello"}'
```

```python
# Compile TypeScript websocket client SDK
aq ws gen-client --out=frontend/src/sdk --lang=ts
```



---

## Deploy & Production Commands
**URL**: `https://tubox.cloud/docs/cli/deploy`

CLI / Deploy Deploy & Production Commands The aq deploy command group generates production-ready deployment configurations (Docker, Kubernetes, reverse-proxy configs, monitoring dashboards) by scanning your active workspace modules. aq deploy dockerfile Generates optimized multi-stage Dockerfiles configured for compiled Aquilia artifacts. # Generate standard production Dockerfile aq deploy dockerfile # Generate development Dockerfile with hot reload aq deploy dockerfile --dev Options Option Description ))} aq deploy compose Generates a docker-compose.yml file containing configuration details of databases, caches, proxies, and schedulers matching your modules. # Generate docker-compose config aq deploy compose # Include Prometheus and Grafana monitoring stacks aq deploy compose --monitoring aq deploy kubernetes Generates a complete suite of Kubernetes manifest templates, including: Deployments & Services: Standard ASGI app process pod declarations. Ingress & HPA: Auto-scaler resources and routing maps. Secrets & ConfigMaps: Safe storage injection mapping environment variables. aq deploy kubernetes --output=deploy/k8s aq deploy nginx Scaffolds an Nginx reverse proxy server block, pre-configured with security headers, SSL directives, gzip compression, and websocket connection upgrades. aq deploy nginx aq deploy ci Creates automated continuous integration pipeline configurations (GitHub Actions or GitLab CI) to test, compile manifests, run doctor diagnostics, and build images. # GitHub Actions workflow aq deploy ci --provider=github # GitLab CI configuration aq deploy ci --provider=gitlab aq deploy monitoring Generates Prometheus scrape configurations and Grafana dashboard files to monitor request counts, latency, memory use, cache hits, and queue metrics. aq deploy monitoring aq deploy env Scaffolds a clean .env.example file populated with all configurable configuration keys detected in your modules and workspace settings. aq deploy env aq deploy makefile Generates a convenience Makefile with standard targets: make run, make test, make compile, make build, and make migrate. aq deploy makefile aq deploy all Utility command that runs all deploy command generators at once, outputting a complete, ready-to-run deploy folder. aq deploy all --monitoring --ci-provider=github )

### Code Examples
```python
# Generate standard production Dockerfile
aq deploy dockerfile

# Generate development Dockerfile with hot reload
aq deploy dockerfile --dev
```

```python
# Generate docker-compose config
aq deploy compose

# Include Prometheus and Grafana monitoring stacks
aq deploy compose --monitoring
```

```python
# GitHub Actions workflow
aq deploy ci --provider=github

# GitLab CI configuration
aq deploy ci --provider=gitlab
```



---

## Artifact Commands
**URL**: `https://tubox.cloud/docs/cli/artifacts`

CLI / Artifacts Artifact Commands The aq artifact command group coordinates build registries, verifies signatures, and manages compiled releases. aq artifact list Lists built artifacts inside the store folder, with options to filter by tags or kind type. # List all artifacts in default directory aq artifact list # Filter to show only compiled route model artifacts aq artifact list --kind=routes --tag=env=prod Options Option Description ))} aq artifact inspect Dumps raw metadata, digital signatures, and target files compiled within the designated `.surp` archive. aq artifact inspect package-id-abc aq artifact verify Computes hashes and checks cryptographic signatures on compiled artifacts to ensure they match deployment records. # Verify single artifact integrity aq artifact verify package-id-abc # Batch verify all files in registry aq artifact verify-all aq artifact gc Garbage collects unreferenced files or stale release bundles to free up storage space. aq artifact gc --days-older-than=30 )

### Code Examples
```python
# List all artifacts in default directory
aq artifact list

# Filter to show only compiled route model artifacts
aq artifact list --kind=routes --tag=env=prod
```

```python
# Verify single artifact integrity
aq artifact verify package-id-abc

# Batch verify all files in registry
aq artifact verify-all
```



---

## Subsystem Diagnostics
**URL**: `https://tubox.cloud/docs/cli/subsystems`

CLI / Subsystem Commands Subsystem Diagnostics The Aquilia CLI provides sub-commands to diagnose, inspect, and flush resources for specific modules: Cache, Mail, and i18n Translations. aq cache Commands to introspect active cache adapters and clear keys: aq cache status: Logs the current cache hits/misses statistics, configured backend (Redis, Memcached, SQLite, Memory), and pool size. aq cache keys: Lists active keys. Supports pattern-based glob matching (e.g. aq cache keys "users:*"). aq cache clear: Flushes all active keys or matching patterns. # Clear cached data matching pattern aq cache clear --pattern="products:*" aq mail Validates mail configurations and tests connections to SMTP servers: aq mail status: Displays the mail provider settings (SMTP, SendGrid, Mailgun) and verifies active authentication credentials. aq mail send: Dispatches a test email to verify correct connection routing. # Send a diagnostic test email aq mail send --to=admin@my-domain.com --subject="Test" --body="OK" aq i18n Coordinates localization translation catalogs, scanning files and compiling formats: aq i18n extract: Scans controller routes, Jinja templates, and validation schemas, extracting translatable strings into `.pot` templates. aq i18n compile: Compiles human-readable `.po` localization catalogs into binary `.mo` catalog mappings for fast lookup. # Compile language catalogs aq i18n compile )

### Code Examples
```python
# Clear cached data matching pattern
aq cache clear --pattern="products:*"
```

```python
# Send a diagnostic test email
aq mail send --to=admin@my-domain.com --subject="Test" --body="OK"
```

```python
# Compile language catalogs
aq i18n compile
```



---

## Testing Framework
**URL**: `https://tubox.cloud/docs/testing`

Tooling / Testing Testing Framework Aquilia provides a batteries-included testing framework designed to test async controllers, background jobs, DB integrations, and WebSocket endpoints. It features automated server lifecycle hooks, DI mocking containers, mock storage, and custom assertions. Testing Architecture Testing in Aquilia avoids slow network calls and side effects by leveraging in-process ASGI loops. It connects your tests directly to the dependency container, permitting run-time provider swapping: , , ].map((item, i) => ( ))} Writing Your First Test Subclass AquiliaTestCase to write an integration test. The server automatically starts up before the test runs and self-terminates on completion: from aquilia.testing import AquiliaTestCase from myapp.manifests import users_manifest class TestUserAPI(AquiliaTestCase): # Specify the manifests to load into the test server manifests = [users_manifest] # Overwrite configuration fields settings = } async def test_create_user(self): # Trigger an HTTP post response = await self.client.post("/api/users", json= ) # Use built-in assertions self.assert_status(response, 201) self.assert_json_path(response, "username", "testguy") Framework Reference , , , ].map((sec, i) => ( → ))} CLI OpenAPI )

### Code Examples
```python
from aquilia.testing import AquiliaTestCase
from myapp.manifests import users_manifest

class TestUserAPI(AquiliaTestCase):
    # Specify the manifests to load into the test server
    manifests = [users_manifest]
    
    # Overwrite configuration fields
    settings = {
        "debug": True,
        "database": {"url": "sqlite:///:memory:"}
    }

    async def test_create_user(self):
        # Trigger an HTTP post
        response = await self.client.post("/api/users", json={
            "username": "testguy",
            "email": "test@example.com"
        })
        
        # Use built-in assertions
        self.assert_status(response, 201)
        self.assert_json_path(response, "username", "testguy")
```



---

## TestClient & WebSockets
**URL**: `https://tubox.cloud/docs/testing/client`

Testing / TestClient TestClient & WebSockets TestClient provides an in-process ASGI runner that executes mock HTTP requests and streams, recording responses without binding to a network port. The WebSocketTestClient lets you test real-time event subscriptions and back-channel messages. HTTP Client API The client supports cookie persistence across redirects, customizable request headers, query encoding, and file uploads: from aquilia.testing import TestClient async def test_auth_and_uploads(): async with TestClient(app) as client: # Set authorization header for subsequent requests client.set_bearer_token("my-jwt-token") # Perform standard POST with JSON resp = await client.post("/api/posts", json= ) assert resp.status_code == 201 # Perform file upload (multipart/form-data) file_data = b"image bytes data here" resp = await client.post( "/api/avatars", files= , data= ) assert resp.status_code == 200 HTTP Methods Method Call Signature ))} TestResponse API HTTP requests return a TestResponse wrapper instance that packs response statistics, headers, and bodies: resp = await client.get("/api/users/1") # Status codes resp.status_code # e.g., 200 resp.is_success # True if 2xx resp.is_redirect # True if 3xx resp.is_client_error # True if 4xx resp.is_server_error # True if 5xx # Content readers resp.json() # Parsed JSON object (memoized) resp.text # Body string decoded as utf-8 or specified charset resp.body # Raw bytes content # Metadata resp.headers # dict of lowercase headers resp.content_type # Content type string (e.g. "application/json") resp.location # Location redirect header value resp.elapsed # Time taken in milliseconds WebSocket Testing Test WebSocket interactions using WebSocketTestClient , which mirrors connection states and message channels asynchronously: from aquilia.testing import WebSocketTestClient async def test_websocket_messaging(): # Instantiate client over your ASGI server async with WebSocketTestClient(app) as ws: # Initiate connection handshake await ws.connect("/ws/events") assert ws.is_connected # Send text or JSON events await ws.send_json( ) # Receive text or JSON data = await ws.receive_json(timeout=2.0) assert data["event"] == "pong" # Terminate connection await ws.close(code=1000) WebSocket Methods Method / Attribute Description ))} )

### Code Examples
```python
from aquilia.testing import TestClient

async def test_auth_and_uploads():
    async with TestClient(app) as client:
        # Set authorization header for subsequent requests
        client.set_bearer_token("my-jwt-token")
        
        # Perform standard POST with JSON
        resp = await client.post("/api/posts", json={"title": "Hello"})
        assert resp.status_code == 201
        
        # Perform file upload (multipart/form-data)
        file_data = b"image bytes data here"
        resp = await client.post(
            "/api/avatars",
            files={"avatar": ("profile.png", file_data, "image/png")},
            data={"caption": "New Profile"}
        )
        assert resp.status_code == 200
```

```python
resp = await client.get("/api/users/1")

# Status codes
resp.status_code        # e.g., 200
resp.is_success         # True if 2xx
resp.is_redirect        # True if 3xx
resp.is_client_error    # True if 4xx
resp.is_server_error    # True if 5xx

# Content readers
resp.json()             # Parsed JSON object (memoized)
resp.text               # Body string decoded as utf-8 or specified charset
resp.body               # Raw bytes content

# Metadata
resp.headers            # dict of lowercase headers
resp.content_type       # Content type string (e.g. "application/json")
resp.location           # Location redirect header value
resp.elapsed            # Time taken in milliseconds
```

```python
from aquilia.testing import WebSocketTestClient

async def test_websocket_messaging():
    # Instantiate client over your ASGI server
    async with WebSocketTestClient(app) as ws:
        # Initiate connection handshake
        await ws.connect("/ws/events")
        assert ws.is_connected
        
        # Send text or JSON events
        await ws.send_json({"event": "ping", "data": "hello"})
        
        # Receive text or JSON
        data = await ws.receive_json(timeout=2.0)
        assert data["event"] == "pong"
        
        # Terminate connection
        await ws.close(code=1000)
```



---

## Test Case Classes
**URL**: `https://tubox.cloud/docs/testing/cases`

Testing / Test Cases Test Case Classes Aquilia features a set of test case subclasses tailored for various degrees of infrastructure dependency. These base classes automate uvicorn starting/stopping, manage database transaction rollbacks, and expose testing properties. Test Case Hierarchy Choose the appropriate test class depending on your test scope to maximize execution speed and correctness: , , , ].map((tc, i) => ( ))} Lifecycle & Configurations For AquiliaTestCase and its subclasses, you configure dependencies and subsystem integrations using class-level attributes: Attribute Type Purpose ))} from aquilia.testing import AquiliaTestCase from myapp.manifests import api_manifest class TestBillingFlows(AquiliaTestCase): manifests = [api_manifest] enable_cache = True enable_auth = True settings = , "cache": } async def test_checkout(self): # Cache and Auth systems are automatically active here ... Test Properties & Helpers When running AquiliaTestCase , several properties and helper methods are exposed on the class instance: Instance Properties di_container: Direct access to the active Container instance of the test server, letting you manually resolve or check dependencies. fault_engine: Reference to the running FaultEngine (or MockFaultEngine). config: The active config loader reference. controller_router: The route table resolver, containing all registered HTTP paths. cache_service: Exposes the running cache manager if enable_cache=True. Utility Methods get_url(route_name, **params): Resolves a named controller route pattern back into an absolute URI path (e.g. self.get_url("get_user", id="123") yields "/users/123"). login(username, password): Convenience helper that issues a POST to /auth/login containing credentials, returning the HTTP response. )

### Code Examples
```python
from aquilia.testing import AquiliaTestCase
from myapp.manifests import api_manifest

class TestBillingFlows(AquiliaTestCase):
    manifests = [api_manifest]
    enable_cache = True
    enable_auth = True
    settings = {
        "billing": {"gateway": "mock-stripe"},
        "cache": {"backend": "memory"}
    }

    async def test_checkout(self):
        # Cache and Auth systems are automatically active here
        ...
```



---

## Mocks & Test Mixins
**URL**: `https://tubox.cloud/docs/testing/mocks`

Testing / Mocks & Mixins Mocks & Test Mixins Aquilia provides specialized mock objects, context overrides, and testing mixins. Swap dependencies, assert on background flows, and inspect side-effects cleanly from your tests. MockFaultEngine MockFaultEngine replaces the framework default FaultEngine during test phases, capturing all raised faults into an internal list instead of dispatching them to production handlers. from aquilia.testing import MockFaultEngine from aquilia.faults import Fault # Setup engine engine = MockFaultEngine() # Simulate code emitting a fault my_fault = Fault(code="DATABASE_TIMEOUT", message="DB took too long") engine.emit(my_fault, app_name="billing") # Check captured faults assert engine.has_fault("DATABASE_TIMEOUT") assert engine.fault_count == 1 assert engine.last_fault_code == "DATABASE_TIMEOUT" # Reset history between assertions engine.reset() assert engine.fault_count == 0 Testing Assertions If you subclass AquiliaTestCase , you gain access to the following fault assertion methods: self.assert_fault_raised(engine, code=None, domain=None): Asserts that at least one fault matching the code or domain was captured. self.assert_no_faults(engine): Asserts that no faults were captured. self.assert_fault_count(engine, expected): Asserts that exactly the expected number of faults were captured. MockEffectRegistry & MockFlowContext The effect system isolates side effects like databases, cache backends, and task queues. With MockEffectRegistry and MockFlowContext, you can stub these operations and inject mock values into your pipeline handlers: from aquilia.testing import MockEffectRegistry, MockFlowContext # Create registry and register mock effects registry = MockEffectRegistry() mock_db = registry.register_mock("DBTx", return_value="fake_connection") # Acquire effect resources provider = registry.get_provider("DBTx") conn = await provider.acquire(mode="write") assert conn == "fake_connection" assert provider.acquire_count == 1 # Setup sequential returns (for multiple calls) mock_cache = registry.register_mock("Cache", return_sequence=["val1", "val2"]) provider_cache = registry.get_provider("Cache") assert await provider_cache.acquire() == "val1" assert await provider_cache.acquire() == "val2" assert await provider_cache.acquire() == "val2" # Repeats last item # Inject into MockFlowContext for pipeline node testing ctx = MockFlowContext.from_registry(registry) db_resource = ctx.get_effect("DBTx") assert db_resource == "fake_connection" Dependency Injection Overrides Aquilia's DI system includes testing helpers to override services and monitor calls within the container: mock_provider(token, value): Creates a mock provider that resolves to a fixed stub object. override_provider(container, token, mock_value): Async context manager that temporarily swaps a token provider in the container, restoring the original on exit. spy_provider(container, token): Async context manager that wraps a real provider. It monitors and logs instantiation counts and values, but still delegates calls to the real service. from aquilia.testing import override_provider, spy_provider class TestServiceDI(AquiliaTestCase): async def test_repository_override(self): # Override the real database repo with a mock repo fake_repo = MockUserRepository() async with override_provider(self.di_container, UserRepository, fake_repo): resolved = await self.di_container.resolve_async(UserRepository) assert resolved is fake_repo async def test_email_spy(self): # Spy on the real email service async with spy_provider(self.di_container, EmailService) as spy: # Trigger logic that invokes EmailService await self.client.post("/api/register", json= ) # Assert details on spy assert spy.resolve_count == 1 assert len(spy.resolved_values) == 1 Subsystem Mixins Aquilia includes three mixins to easily interact with and assert on cache, authentication, and mail payloads: 1. CacheTestMixin Integrates cache assertions. Automatically hooks into self.cache_service: self.populate_cache(data, ttl=None): Populate keys into the cache. self.assert_cached(key): Assert key is present. self.assert_not_cached(key): Assert key is missing. self.assert_cache_value(key, expected): Assert key value matches expected. self.assert_cache_count(expected, pattern="*"): Assert number of matching keys. self.flush_cache(): Flush all keys. 2. AuthTestMixin Enables quick authentication mocking, letting you bypass credential verification: self.force_login(identity): Injects an identity into the TestClient session headers, making subsequent requests appear authenticated. self.authenticate_as(identity): thorough than force_login, registers the identity directly into the server's identity store. self.login_as_admin(id=None, **kw): Helper that builds an admin identity and authenticates it. self.login_as_user(id=None, **kw): Helper that builds a regular user identity and authenticates it. from aquilia.testing import AquiliaTestCase, AuthTestMixin class TestBilling(AuthTestMixin, AquiliaTestCase): enable_auth = True async def test_access_billing(self): # Build and authenticate user identity self.login_as_admin(id="user-123", email="admin@test.com") # Injected identity header is sent automatically resp = await self.client.get("/api/billing") self.assert_status(resp, 200) 3. MailTestMixin Captures outgoing emails sent via the mail subsystem, placing them in an outbox array instead of triggering SMTP: self.mail_outbox: Read-only list containing all sent CapturedMail objects. self.latest_mail: Returns the most recently sent CapturedMail object. self.assert_mail_count(outbox, expected): Asserts exact number of sent messages. self.assert_mail_to(outbox, address): Asserts email was sent to address. )

### Code Examples
```python
from aquilia.testing import MockFaultEngine
from aquilia.faults import Fault

# Setup engine
engine = MockFaultEngine()

# Simulate code emitting a fault
my_fault = Fault(code="DATABASE_TIMEOUT", message="DB took too long")
engine.emit(my_fault, app_name="billing")

# Check captured faults
assert engine.has_fault("DATABASE_TIMEOUT")
assert engine.fault_count == 1
assert engine.last_fault_code == "DATABASE_TIMEOUT"

# Reset history between assertions
engine.reset()
assert engine.fault_count == 0
```

```python
from aquilia.testing import MockEffectRegistry, MockFlowContext

# Create registry and register mock effects
registry = MockEffectRegistry()
mock_db = registry.register_mock("DBTx", return_value="fake_connection")

# Acquire effect resources
provider = registry.get_provider("DBTx")
conn = await provider.acquire(mode="write")
assert conn == "fake_connection"
assert provider.acquire_count == 1

# Setup sequential returns (for multiple calls)
mock_cache = registry.register_mock("Cache", return_sequence=["val1", "val2"])
provider_cache = registry.get_provider("Cache")
assert await provider_cache.acquire() == "val1"
assert await provider_cache.acquire() == "val2"
assert await provider_cache.acquire() == "val2"  # Repeats last item

# Inject into MockFlowContext for pipeline node testing
ctx = MockFlowContext.from_registry(registry)
db_resource = ctx.get_effect("DBTx")
assert db_resource == "fake_connection"
```

```python
from aquilia.testing import override_provider, spy_provider

class TestServiceDI(AquiliaTestCase):
    async def test_repository_override(self):
        # Override the real database repo with a mock repo
        fake_repo = MockUserRepository()
        async with override_provider(self.di_container, UserRepository, fake_repo):
            resolved = await self.di_container.resolve_async(UserRepository)
            assert resolved is fake_repo

    async def test_email_spy(self):
        # Spy on the real email service
        async with spy_provider(self.di_container, EmailService) as spy:
            # Trigger logic that invokes EmailService
            await self.client.post("/api/register", json={"email": "alice@test.com"})
            
            # Assert details on spy
            assert spy.resolve_count == 1
            assert len(spy.resolved_values) == 1
```



---

## aq test — Test Runner
**URL**: `https://tubox.cloud/docs/testing/runner`

Testing / Test Runner aq test — Test Runner The aq test CLI command is Aquilia's built-in test runner. It wraps pytest, automatically sets test environments, discovers workspace-wide test structures, and executes specs with optimized asyncio profiles. Runner Architecture & Lifecycle Executing tests in a manifest-driven architecture requires configuring global configurations and mock files before loading modules. The test runner streamlines this by wrapping the standard pytest execution pipeline: , , ].map((item, i) => ( ))} Test CLI Command Options Below are the Click arguments and flags supported by the aq test command: Option / Argument Description ))} Writing Pytest-native Tests While unittest is supported natively via AquiliaTestCase , you can write native pytest functions and utilize fixtures: Mocks & Fixtures CLI Overview )

### Code Examples
```python
# Run the entire discovered test suite
aq test

# Run tests in a specific module only
aq test modules/billing/tests/

# Filter execution to test names matching "login"
aq test -k "login"

# Run tests with coverage collection and HTML report output
aq test --coverage --coverage-html

# Stop immediately on the first assertion failure
aq test -x
```

```python
import pytest
from aquilia.testing import TestClient
from myapp.manifests import api_manifest

@pytest.fixture
def test_app():
    # Setup your workspace application test environment
    from aquilia.server import AquiliaServer
    return AquiliaServer(manifests=[api_manifest])

@pytest.mark.asyncio
async def test_api_endpoint(test_app):
    async with TestClient(test_app) as client:
        resp = await client.get("/health")
        assert resp.status_code == 200
        assert resp.json()["status"] == "healthy"
```



---

## Background Tasks Module
**URL**: `https://tubox.cloud/docs/tasks`

import from 'lucide-react' Background Tasks / Overview Background Tasks Module Aquilia provides an industry-grade, async-native background task system with priority queues, automatic retries, and scheduled executions. It is a lightweight, integrated replacement for Celery or RQ, running directly inside the asyncio event loop. Quick Start 1. Enable in Workspace Register the task integration inside your workspace.py config using TasksIntegration . # workspace.py from aquilia import Workspace, Module from aquilia.integrations import TasksIntegration workspace = ( Workspace("myapp", version="1.0.0") .runtime(mode="dev", port=8000) .module(Module("core")) .integrate(TasksIntegration( num_workers=4, scheduler_tick=15.0, # Periodic check interval )) ) 2. Define a Task Decorate an async function with @task and configure its queue, priority, and retry policy. # modules/core/tasks.py from aquilia.tasks import task, Priority @task( queue="notifications", priority=Priority.HIGH, max_retries=3, timeout=60.0, ) async def send_notification(user_id: int, message: str) -> bool: """Send a notification to a user.""" # notification logic goes here return True 3. Dispatch from a Controller Call the task asynchronously inside a Controller handler using .delay(). # modules/core/controllers.py from aquilia import Controller, POST, RequestCtx, Response from .tasks import send_notification class NotificationsController(Controller): prefix = "/notifications" @POST("/send") async def send(self, ctx: RequestCtx) -> Response: data = await ctx.json() # Enqueue task for background execution (returns job ID string) job_id = await send_notification.delay( user_id=data["user_id"], message=data["message"] ) return Response.json( ) Key Pillars ))} Subsystem Architecture SCHEDULER every() & cron() Generates periodic triggers TASK MANAGER Registry Lookup Orchestrates lifecycles QUEUE BACKEND Priority Heap Memory Heap queue storage WORKER POOL Async Coroutines Concurrent execution loops Tick check delay() poll() JOB LIFECYCLE STATES , , , , , , ].map((s, i) => ( ))} Job Lifecycle States , , , , , , ].map((item, i) => ( ))} Priority System Aquilia background jobs are ordered in the queue using their integer priority. Lower values take absolute precedence. Level Enum Member Value Typical Use Case , , , ].map((row, i) => ( ))} Subsystem Comparison Feature Aquilia Tasks Celery RQ (Redis Queue) ))} )

### Code Examples
```python
# workspace.py
from aquilia import Workspace, Module
from aquilia.integrations import TasksIntegration

workspace = (
    Workspace("myapp", version="1.0.0")
    .runtime(mode="dev", port=8000)
    .module(Module("core"))
    .integrate(TasksIntegration(
        num_workers=4,
        scheduler_tick=15.0,  # Periodic check interval
    ))
)
```

```python
# modules/core/tasks.py
from aquilia.tasks import task, Priority

@task(
    queue="notifications",
    priority=Priority.HIGH,
    max_retries=3,
    timeout=60.0,
)
async def send_notification(user_id: int, message: str) -> bool:
    """Send a notification to a user."""
    # notification logic goes here
    return True
```

```python
# modules/core/controllers.py
from aquilia import Controller, POST, RequestCtx, Response
from .tasks import send_notification

class NotificationsController(Controller):
    prefix = "/notifications"
    
    @POST("/send")
    async def send(self, ctx: RequestCtx) -> Response:
        data = await ctx.json()
        
        # Enqueue task for background execution (returns job ID string)
        job_id = await send_notification.delay(
            user_id=data["user_id"],
            message=data["message"]
        )
        
        return Response.json({
            "job_id": job_id,
            "status": "queued"
        })
```



---

## Tasks API Reference
**URL**: `https://tubox.cloud/docs/tasks/api`

Background Tasks / API Reference Tasks API Reference Complete interface specifications for background task decorators, coordinates, workers, and schedulers, compiled from the actual implementation in aquilia/tasks/. Table of Contents , , , , , , , , , , ].map((item, i) => ( • ))} @task Decorator to register an async function as a background task. Can be used with or without parentheses. from aquilia.tasks import task, Priority, every, cron def task( fn=None, *, name: str | None = None, queue: str = "default", priority: Priority = Priority.NORMAL, max_retries: int = 3, retry_delay: float = 1.0, retry_backoff: float = 2.0, retry_max_delay: float = 300.0, timeout: float = 300.0, tags: list[str] | None = None, schedule: Schedule | None = None, ) -> _TaskDescriptor Parameters Parameter Type Default Description ))} TaskManager Central coordinator for creating, routing, enqueuing, and querying background tasks. class TaskManager: def __init__( self, *, backend: TaskBackend | None = None, # MemoryBackend() by default num_workers: int = 4, default_queue: str = "default", cleanup_interval: float = 300.0, # Seconds between cleanup runs cleanup_max_age: float = 3600.0, # Job TTL after termination scheduler_tick: float = 15.0, # Scheduler tick frequency ) -> None async def start(self) -> None: """Start worker threads, cleanup loops, and scheduled task loops.""" async def stop(self, timeout: float = 10.0) -> None: """Gracefully stop all worker tasks and loops, waiting up to timeout.""" async def enqueue( self, func: Callable | _TaskDescriptor, *args: Any, queue: str | None = None, priority: Priority | None = None, delay: float | None = None, # Delay execution in seconds max_retries: int | None = None, timeout: float | None = None, tags: list[str] | None = None, metadata: dict[str, Any] | None = None, **kwargs: Any, ) -> str: """Enqueue task and return job ID string.""" async def get_job(self, job_id: str) -> Job | None: """Retrieve job dataclass by ID.""" async def list_jobs( self, *, queue: str | None = None, state: JobState | None = None, limit: int = 100, offset: int = 0, ) -> list[Job]: """List jobs matching filters, ordered created_at DESC.""" async def cancel(self, job_id: str) -> bool: """Cancel a pending/running job. Returns True if successful.""" async def retry_job(self, job_id: str) -> bool: """Manually force-retry a failed/dead/cancelled job.""" async def flush(self, queue: str | None = None) -> int: """Clear all tasks (or filtered by queue). Returns number of cleared jobs.""" async def get_stats(self) -> dict[str, Any]: """Return comprehensive TaskManager metrics, uptime, and Chart.js datasets.""" Job Dataclass representing the immutable job configuration and mutable execution state. @dataclass class Job: id: str # Hexadecimal UUID prefix (16 chars) name: str # Human readable task name queue: str = "default" priority: Priority = Priority.NORMAL func_ref: str = "" # module:qualname path args: tuple[Any, ...] = () kwargs: dict[str, Any] = field(default_factory=dict) state: JobState = JobState.PENDING result: JobResult | None = None max_retries: int = 3 retry_count: int = 0 created_at: datetime = datetime.now(timezone.utc) started_at: datetime | None = None completed_at: datetime | None = None scheduled_at: datetime | None = None # Set when executing with delay timeout: float = 300.0 metadata: dict[str, Any] = field(default_factory=dict) tags: list[str] = field(default_factory=list) @property def is_terminal(self) -> bool: """Returns True if state is COMPLETED, FAILED, CANCELLED, or DEAD.""" @property def is_runnable(self) -> bool: """Returns True if job is pending/scheduled and scheduled_at has passed.""" @property def next_retry_delay(self) -> float: """Computes next backoff delay with exponential backoff and random jitter.""" @property def can_retry(self) -> bool: """Returns True if retry_count float | None: """Duration of job execution in milliseconds.""" @property def fingerprint(self) -> str: """SHA-256 fingerprint for enqueued parameter deduplication.""" JobResult Container representing task execution outcomes, exceptions, and execution metrics. @dataclass class JobResult: success: bool value: Any = None # Return value (converted to repr() string on dict serialization) error: str | None = None # Exception message error_type: str | None = None # Name of Exception class traceback: str | None = None # Formatted traceback string duration_ms: float = 0.0 # Millisecond execution time Priority Integer enumeration specifying job urgency. Lower values represent higher priority. class Priority(int, Enum): CRITICAL = 0 HIGH = 1 NORMAL = 2 LOW = 3 JobState Lifecycle states for a task job. class JobState(str, Enum): PENDING = "pending" # Waiting in queue SCHEDULED = "scheduled" # Waiting for delayed timestamp RUNNING = "running" # Undergoing worker processing COMPLETED = "completed" # Executed successfully FAILED = "failed" # Failed, pending retry RETRYING = "retrying" # Rescheduled for retry CANCELLED = "cancelled" # Terminated by admin action DEAD = "dead" # Exhausted all retries (sent to dead letter) Schedule Helpers Helper methods to generate periodic task schedules for the scheduler loop. every() def every( *, seconds: float = 0, minutes: float = 0, hours: float = 0, days: float = 0, ) -> IntervalSchedule cron() def cron(expression: str) -> CronSchedule Accepts standard 5-field cron syntax: "minute hour dom month dow". Registry Queries Access internally mapped tasks registered via decorators. def get_registered_tasks() -> dict[str, _TaskDescriptor]: """Retrieve mapping of all task names to their descriptors.""" def get_periodic_tasks() -> dict[str, _TaskDescriptor]: """Retrieve mapping of only scheduled/periodic tasks.""" def get_task(name: str) -> _TaskDescriptor | None: """Look up a task descriptor by its registered name.""" Integration Builder Option Configures background tasks at the workspace level. # from aquilia.integrations import Integration @staticmethod def tasks( backend: str = "memory", num_workers: int = 4, default_queue: str = "default", cleanup_interval: float = 300.0, cleanup_max_age: float = 3600.0, max_retries: int = 3, retry_delay: float = 1.0, retry_backoff: float = 2.0, retry_max_delay: float = 300.0, default_timeout: float = 300.0, auto_start: bool = True, dead_letter_max: int = 1000, scheduler_tick: float = 15.0, enabled: bool = True, ) -> dict[str, Any] Structured Faults Specific errors raised by the tasks subsystem under the "tasks" fault domain. Fault Triggers ))} )

### Code Examples
```python
from aquilia.tasks import task, Priority, every, cron

def task(
    fn=None,
    *,
    name: str | None = None,
    queue: str = "default",
    priority: Priority = Priority.NORMAL,
    max_retries: int = 3,
    retry_delay: float = 1.0,
    retry_backoff: float = 2.0,
    retry_max_delay: float = 300.0,
    timeout: float = 300.0,
    tags: list[str] | None = None,
    schedule: Schedule | None = None,
) -> _TaskDescriptor
```

```python
class TaskManager:
    def __init__(
        self,
        *,
        backend: TaskBackend | None = None,   # MemoryBackend() by default
        num_workers: int = 4,
        default_queue: str = "default",
        cleanup_interval: float = 300.0,      # Seconds between cleanup runs
        cleanup_max_age: float = 3600.0,      # Job TTL after termination
        scheduler_tick: float = 15.0,         # Scheduler tick frequency
    ) -> None

    async def start(self) -> None:
        """Start worker threads, cleanup loops, and scheduled task loops."""

    async def stop(self, timeout: float = 10.0) -> None:
        """Gracefully stop all worker tasks and loops, waiting up to timeout."""

    async def enqueue(
        self,
        func: Callable | _TaskDescriptor,
        *args: Any,
        queue: str | None = None,
        priority: Priority | None = None,
        delay: float | None = None,            # Delay execution in seconds
        max_retries: int | None = None,
        timeout: float | None = None,
        tags: list[str] | None = None,
        metadata: dict[str, Any] | None = None,
        **kwargs: Any,
    ) -> str:
        """Enqueue task and return job ID string."""

    async def get_job(self, job_id: str) -> Job | None:
        """Retrieve job dataclass by ID."""

    async def list_jobs(
        self,
        *,
        queue: str | None = None,
        state: JobState | None = None,
        limit: int = 100,
        offset: int = 0,
    ) -> list[Job]:
        """List jobs matching filters, ordered created_at DESC."""

    async def cancel(self, job_id: str) -> bool:
        """Cancel a pending/running job. Returns True if successful."""

    async def retry_job(self, job_id: str) -> bool:
        """Manually force-retry a failed/dead/cancelled job."""

    async def flush(self, queue: str | None = None) -> int:
        """Clear all tasks (or filtered by queue). Returns number of cleared jobs."""

    async def get_stats(self) -> dict[str, Any]:
        """Return comprehensive TaskManager metrics, uptime, and Chart.js datasets."""
```

```python
@dataclass
class Job:
    id: str                                  # Hexadecimal UUID prefix (16 chars)
    name: str                                # Human readable task name
    queue: str = "default"
    priority: Priority = Priority.NORMAL
    func_ref: str = ""                       # module:qualname path
    args: tuple[Any, ...] = ()
    kwargs: dict[str, Any] = field(default_factory=dict)
    state: JobState = JobState.PENDING
    result: JobResult | None = None
    max_retries: int = 3
    retry_count: int = 0
    created_at: datetime = datetime.now(timezone.utc)
    started_at: datetime | None = None
    completed_at: datetime | None = None
    scheduled_at: datetime | None = None    # Set when executing with delay
    timeout: float = 300.0
    metadata: dict[str, Any] = field(default_factory=dict)
    tags: list[str] = field(default_factory=list)

    @property
    def is_terminal(self) -> bool:
        """Returns True if state is COMPLETED, FAILED, CANCELLED, or DEAD."""

    @property
    def is_runnable(self) -> bool:
        """Returns True if job is pending/scheduled and scheduled_at has passed."""

    @property
    def next_retry_delay(self) -> float:
        """Computes next backoff delay with exponential backoff and random jitter."""

    @property
    def can_retry(self) -> bool:
        """Returns True if retry_count < max_retries."""

    @property
    def duration_ms(self) -> float | None:
        """Duration of job execution in milliseconds."""

    @property
    def fingerprint(self) -> str:
        """SHA-256 fingerprint for enqueued parameter deduplication."""
```



---

## Tasks Configuration
**URL**: `https://tubox.cloud/docs/tasks/configuration`

Background Tasks / Configuration Tasks Configuration Complete configuration specifications for background tasks. Learn how to configure workers, retries, periodic intervals, and custom backends at the workspace and module levels. Integration Configuration Styles Aquilia supports two styles of declaring subsystem integrations within workspace.py: the legacy builder-class style and the modern typed-dataclass style. Modern Style: Composed Dataclasses (Recommended) Construct the TasksIntegration class directly. This ensures compile-time validation, IDE type hinting, and strict parameter checking. # workspace.py from aquilia import Workspace, Module from aquilia.integrations import TasksIntegration workspace = ( Workspace("myapp") .module(Module("core")) .integrate(TasksIntegration( backend="memory", num_workers=8, default_queue="default", scheduler_tick=5.0, cleanup_interval=60.0, cleanup_max_age=600.0, max_retries=5, retry_delay=1.5, retry_backoff=2.0, retry_max_delay=120.0, default_timeout=180.0, dead_letter_max=500, auto_start=True )) ) Legacy Style: Static Integration Builders The legacy Integration.tasks() helper delegates to the modern TasksIntegration under the hood. Avoid this in new projects. # workspace.py (Legacy) from aquilia import Workspace from aquilia.integrations import Integration workspace = ( Workspace("myapp") .integrate(Integration.tasks( num_workers=4, scheduler_tick=15.0, )) ) Warning: The legacy static helper Integration.tasks() is deprecated and will be removed in a future release. Migrate to direct constructor calls using TasksIntegration. TasksIntegration Parameters Parameter Type Default Description ))} Module Manifest & ComponentRef Instead of declaring component imports as bare string paths, Aquilia v2 recommends using the ComponentRef class inside manifest.py. This offers typed metadata checks during boot scans. # modules/core/manifest.py from aquilia import AppManifest, ComponentRef, ComponentKind manifest = AppManifest( name="core", controllers=[ # Controller component references ComponentRef( class_path="modules.core.controllers:NotificationsController", kind=ComponentKind.CONTROLLER ) ], tasks=[ # Task component references ComponentRef( class_path="modules.core.tasks:send_notification", kind=ComponentKind.TASK ), ComponentRef( class_path="modules.core.tasks:cleanup_logs", kind=ComponentKind.TASK ) ], ) Direct TaskManager Setup To run task workers in standalone scripts, background processes, or daemon systems, construct the manager manually: import asyncio from aquilia.tasks import TaskManager, MemoryBackend async def run_worker(): backend = MemoryBackend() manager = TaskManager( backend=backend, num_workers=4, scheduler_tick=1.0 ) await manager.start() try: # Keep running while True: await asyncio.sleep(3600) finally: await manager.stop() if __name__ == "__main__": asyncio.run(run_worker()) )

### Code Examples
```python
# workspace.py
from aquilia import Workspace, Module
from aquilia.integrations import TasksIntegration

workspace = (
    Workspace("myapp")
    .module(Module("core"))
    .integrate(TasksIntegration(
        backend="memory",
        num_workers=8,
        default_queue="default",
        scheduler_tick=5.0,
        cleanup_interval=60.0,
        cleanup_max_age=600.0,
        max_retries=5,
        retry_delay=1.5,
        retry_backoff=2.0,
        retry_max_delay=120.0,
        default_timeout=180.0,
        dead_letter_max=500,
        auto_start=True
    ))
)
```

```python
# workspace.py (Legacy)
from aquilia import Workspace
from aquilia.integrations import Integration

workspace = (
    Workspace("myapp")
    .integrate(Integration.tasks(
        num_workers=4,
        scheduler_tick=15.0,
    ))
)
```

```python
# modules/core/manifest.py
from aquilia import AppManifest, ComponentRef, ComponentKind

manifest = AppManifest(
    name="core",
    controllers=[
        # Controller component references
        ComponentRef(
            class_path="modules.core.controllers:NotificationsController",
            kind=ComponentKind.CONTROLLER
        )
    ],
    tasks=[
        # Task component references
        ComponentRef(
            class_path="modules.core.tasks:send_notification",
            kind=ComponentKind.TASK
        ),
        ComponentRef(
            class_path="modules.core.tasks:cleanup_logs",
            kind=ComponentKind.TASK
        )
    ],
)
```



---

## Retry Logic & Error Handling
**URL**: `https://tubox.cloud/docs/tasks/retry`

Background Tasks / Retry Logic Retry Logic & Error Handling Understand how Aquilia processes background task failures, computes exponential backoffs with jitter, and routes jobs to the dead-letter queue. How Retries are Processed When a task handler raises an unhandled exception, the worker catches the error, increments the retry counter, and determines if it can run again based on the task policy: Exception Intercepted: The worker catches exceptions raised inside the task coroutine. Retry Evaluation: The worker compares job.retry_count to job.max_retries. Backoff Math: If retries remain, the next schedule delay is computed with exponential backoff and ±25% random jitter. State Transition: The job state is updated to JobState.RETRYING . Queue Re-push: The job is pushed back into the heap queue with its scheduled_at timestamp set to the cooldown expiration. Dead-Letter Route: If all retries are exhausted, the job state transitions to JobState.DEAD and is sent to the dead-letter queue. State Transitions RUNNING FAILED RETRYING PENDING DEAD raised error tries remaining backoff delay limit reached scheduled worker poll Exponential Backoff & Jitter To prevent the "thundering herd" problem when external services fail, Aquilia adds a ±25% random jitter to the calculated exponential backoff delay. # Source code from aquilia/tasks/job.py @property def next_retry_delay(self) -> float: """Calculate next retry delay with exponential backoff + jitter.""" import random delay = self.retry_delay * (self.retry_backoff ** self.retry_count) delay = min(delay, self.retry_max_delay) # Add random jitter (±25%) jitter = delay * 0.25 * (2 * random.random() - 1) return max(0.1, delay + jitter) Retry Backoff Intervals (Default Settings) Formula: delay = retry_delay * (retry_backoff ^ attempt) capped at retry_max_delay. Attempt Formula Base Delay Actual Interval (with ±25% jitter) ))} Configuring Retry Policies Aggressive (Short Wait, High Attempts) @task( max_retries=10, retry_delay=0.5, # Start at 500ms retry_backoff=1.5, # Slower exponential curve retry_max_delay=60.0, # Max cap of 1 minute ) async def aggressive_retry_task(): ... Conservative (Long Wait, Low Attempts) @task( max_retries=3, retry_delay=30.0, # Start at 30 seconds retry_backoff=3.0, # Slower exponential curve retry_max_delay=1800.0, # Max cap of 30 minutes ) async def conservative_retry_task(): ... Disable Retries (One-Shot Task) @task(max_retries=0) async def non_retryable_task(): # Any failure routes directly to DEAD state ... Dead-Letter Queues (DLQ) Jobs that exceed `max_retries` transition to the DEAD state. You can monitor, list, and manually trigger retries for dead jobs. from aquilia.tasks import JobState # Query dead jobs from the manager dead_jobs = await manager.list_jobs(state=JobState.DEAD) for job in dead_jobs: print(f"Dead Job ID: | Task: ") print(f"Error: ") # Manually re-enqueue/retry the job await manager.retry_job(job.id) )

### Code Examples
```python
# Source code from aquilia/tasks/job.py
@property
def next_retry_delay(self) -> float:
    """Calculate next retry delay with exponential backoff + jitter."""
    import random

    delay = self.retry_delay * (self.retry_backoff ** self.retry_count)
    delay = min(delay, self.retry_max_delay)
    
    # Add random jitter (±25%)
    jitter = delay * 0.25 * (2 * random.random() - 1)
    return max(0.1, delay + jitter)
```

```python
@task(
    max_retries=10,
    retry_delay=0.5,         # Start at 500ms
    retry_backoff=1.5,       # Slower exponential curve
    retry_max_delay=60.0,    # Max cap of 1 minute
)
async def aggressive_retry_task():
    ...
```

```python
@task(
    max_retries=3,
    retry_delay=30.0,        # Start at 30 seconds
    retry_backoff=3.0,       # Slower exponential curve
    retry_max_delay=1800.0,  # Max cap of 30 minutes
)
async def conservative_retry_task():
    ...
```



---

## Periodic Task Scheduling
**URL**: `https://tubox.cloud/docs/tasks/scheduling`

Background Tasks / Scheduling Periodic Task Scheduling Schedule tasks to run at fixed intervals or precise calendar times. The scheduler loop automatically detects due tasks and enqueues them into the priority queue. How Scheduling Works Aquilia handles scheduling without external services. When TaskManager.start() runs, a dedicated scheduler loop evaluates periodic registrations on every clock tick (determined by scheduler_tick). Task Registration: Tasks decorated with schedule= are registered with the task manager. Tick Loop: The scheduler coroutine wakes up every tick interval (default: 15s) to check due tasks. Due Calculation: The next execution timestamp is calculated based on the interval or cron specification. Job Enqueue: When due, a new Job instance is pushed onto the priority queue. Execution: Available workers pop and execute the task concurrently. SCHEDULER LOOP every() / cron() Wakes up on tick interval TASK QUEUE Priority Heap Due jobs ordered by time WORKER POOL Async Coroutines Execute due jobs enqueue() poll() every() — Interval-based Schedules Specifies that a task runs at fixed intervals. The scheduler calculates intervals dynamically using floats. from aquilia.tasks import task, every @task(schedule=every(seconds=30)) async def report_heartbeat(): # Runs every 30 seconds ... @task(schedule=every(minutes=5)) async def prune_temp_files(): # Runs every 5 minutes ... @task(schedule=every(hours=12)) async def check_database_integrity(): # Runs every 12 hours ... @task(schedule=every(days=1, hours=6)) async def compile_statistics(): # Runs every 30 hours ... Interval Schedule Layout Declaration Total Cooldown Runs Per Day ))} cron() — Calendar-based Schedules Specifies that a task runs on a cron schedule. Supports standard 5-field cron strings. from aquilia.tasks import task, cron # Format: "minute hour day_of_month month day_of_week" @task(schedule=cron("0 9 * * *")) async def daily_9am_reports(): # Runs at exactly 9:00 AM every day ... @task(schedule=cron("*/15 * * * *")) async def sync_external_inventory(): # Runs at :00, :15, :30, and :45 of every hour ... @task(schedule=cron("0 0 1 * *")) async def monthly_invoice_run(): # Runs at midnight on the first day of every month ... Expression Format Specification Position Field Name Valid Values Supported Symbols ))} Scheduling Best Practices , , , , ].map((item, i) => ( ))} )

### Code Examples
```python
from aquilia.tasks import task, every

@task(schedule=every(seconds=30))
async def report_heartbeat():
    # Runs every 30 seconds
    ...

@task(schedule=every(minutes=5))
async def prune_temp_files():
    # Runs every 5 minutes
    ...

@task(schedule=every(hours=12))
async def check_database_integrity():
    # Runs every 12 hours
    ...

@task(schedule=every(days=1, hours=6))
async def compile_statistics():
    # Runs every 30 hours
    ...
```

```python
from aquilia.tasks import task, cron

# Format: "minute hour day_of_month month day_of_week"

@task(schedule=cron("0 9 * * *"))
async def daily_9am_reports():
    # Runs at exactly 9:00 AM every day
    ...

@task(schedule=cron("*/15 * * * *"))
async def sync_external_inventory():
    # Runs at :00, :15, :30, and :45 of every hour
    ...

@task(schedule=cron("0 0 1 * *"))
async def monthly_invoice_run():
    # Runs at midnight on the first day of every month
    ...
```



---

## Unified Storage Subsystem
**URL**: `https://tubox.cloud/docs/storage`

Unified Storage / Overview Unified Storage Subsystem Aquilia provides an async-native, unified storage abstraction that decouples your file management logic from the underlying storage providers. Configure local, in-memory, or cloud backends once, and access them anywhere. Quick Example Configure your storage integrations and interact with your files. Note that unlike legacy frameworks, you access backend instances from the registered StorageRegistry . from aquilia.storage import StorageRegistry from aquilia.storage.backends import LocalStorage, S3Storage from aquilia.storage.configs import LocalConfig, S3Config # Setup registry and backends manually (or let Workspace do it) registry = StorageRegistry() registry.register("local", LocalStorage(LocalConfig(root="./storage"))) registry.register("s3", S3Storage(S3Config(bucket="my-bucket", region="us-east-1"))) registry.set_default("local") # Save a file using the default backend (returns actual saved filename string) saved_path = await registry.default.save("docs/invoice.pdf", b"PDF_DATA") # Open a file as an async stream (returns a StorageFile wrapper) async with await registry.default.open("docs/invoice.pdf") as file: content = await file.read() # read all bytes # Save/access from a specific non-default backend await registry["s3"].save("backups/db.tar.gz", b"TAR_DATA") print(await registry["s3"].exists("backups/db.tar.gz")) Subsystem Features ))} Supported Storage Backends Backend Class Description Library Dependency ))} Architecture STORAGEREGISTRY registry.default Routes alias to backend driver LOCALSTORAGE root: "./uploads" Writes to host filesystem S3STORAGE bucket: "my-bucket" AWS S3 / R2 Cloud Object MEMORYSTORAGE backends: dict Ephemeral RAM storage SFTPSTORAGE host: "remote.com" Remote SSH Transfer )

### Code Examples
```python
from aquilia.storage import StorageRegistry
from aquilia.storage.backends import LocalStorage, S3Storage
from aquilia.storage.configs import LocalConfig, S3Config

# Setup registry and backends manually (or let Workspace do it)
registry = StorageRegistry()
registry.register("local", LocalStorage(LocalConfig(root="./storage")))
registry.register("s3", S3Storage(S3Config(bucket="my-bucket", region="us-east-1")))
registry.set_default("local")

# Save a file using the default backend (returns actual saved filename string)
saved_path = await registry.default.save("docs/invoice.pdf", b"PDF_DATA")

# Open a file as an async stream (returns a StorageFile wrapper)
async with await registry.default.open("docs/invoice.pdf") as file:
    content = await file.read()  # read all bytes
    
# Save/access from a specific non-default backend
await registry["s3"].save("backups/db.tar.gz", b"TAR_DATA")
print(await registry["s3"].exists("backups/db.tar.gz"))
```



---

## Storage API Reference
**URL**: `https://tubox.cloud/docs/storage/api`

Unified Storage / API Reference Storage API Reference Complete interface contract specifications for the unified storage registry, backend drivers, metadata structures, and async file handles. Table of Contents , , , , , ].map((item, i) => ( • ))} StorageRegistry The central coordinator for registering, retrieving, and checking the health of multiple storage backends. class StorageRegistry: def __init__(self) -> None: """Create an empty storage registry.""" @property def default(self) -> StorageBackend: """Get the default registered StorageBackend instance. Raises StorageConfigFault if no default backend is set. """ def register(self, alias: str, backend: StorageBackend) -> None: """Register a backend instance with the given alias name.""" def unregister(self, alias: str) -> None: """Unregister a backend by its alias name.""" def set_default(self, alias: str) -> None: """Define which registered alias acts as the default backend.""" def get(self, alias: str) -> StorageBackend | None: """Look up a backend instance by alias. Returns None if missing.""" def __getitem__(self, alias: str) -> StorageBackend: """Access a backend via bracket notation registry[alias]. Raises KeyError if alias is not found. """ async def initialize_all(self) -> None: """Run the async initialize() lifecycle hook on all registered backends.""" async def shutdown_all(self) -> None: """Close/release connections on all registered backends.""" async def health_check(self) -> dict[str, bool]: """Runs a ping() check on each registered backend. Returns a dictionary of . """ StorageBackend Abstract Base Class establishing the contract all storage drivers (Local, S3, Memory, GCS, SFTP) must implement. from abc import ABC, abstractmethod from collections.abc import AsyncIterator from typing import BinaryIO class StorageBackend(ABC): @property @abstractmethod def backend_name(self) -> str: """Returns the driver name identifier (e.g. 'local', 's3').""" async def initialize(self) -> None: """Bootstrap directory structures, connections, or credential handshakes.""" async def ping(self) -> bool: """Verifies driver accessibility. Returns True if healthy, False otherwise.""" @abstractmethod async def save( self, name: str, content: bytes | BinaryIO | AsyncIterator[bytes] | StorageFile, *, content_type: str | None = None, metadata: dict[str, str] | None = None, overwrite: bool = False, ) -> str: """Save a file to the backend. Args: name: Path/key target. content: Raw byte content, file-like object, or async generator. content_type: MIME string (auto-detected if None). metadata: Custom tag key/values. overwrite: Replaces the file if True, otherwise appends an increments counter. Returns: The final saved relative path string. """ @abstractmethod async def open(self, name: str, mode: str = "rb") -> StorageFile: """Open a file handle for reading or writing. Returns: A StorageFile wrapper. """ @abstractmethod async def delete(self, name: str) -> None: """Deletes a file. Idempotent: does NOT raise if the file does not exist.""" @abstractmethod async def exists(self, name: str) -> bool: """Returns True if the file exists, False otherwise.""" @abstractmethod async def stat(self, name: str) -> StorageMetadata: """Returns metadata for the file. Raises FileNotFoundError if missing.""" @abstractmethod async def listdir(self, path: str = "") -> tuple[list[str], list[str]]: """List subdirectories and files in a path. Returns: A tuple of (directories_list, files_list). """ @abstractmethod async def size(self, name: str) -> int: """Returns the file size in bytes.""" @abstractmethod async def url(self, name: str, expire: int | None = None) -> str: """Generates a public URL or signed temporary URL. Args: expire: URL expiration period in seconds. """ StorageFile An asynchronous wrapper for reading and writing files. Implements the async context manager and iterator protocols. class StorageFile: @property def closed(self) -> bool: """Returns True if the file has been closed.""" async def read(self, size: int = -1) -> bytes: """Read up to size bytes. If -1, reads the entire file.""" async def write(self, data: bytes) -> int: """Write bytes to the file (requires a writable open mode).""" async def seek(self, offset: int, whence: int = 0) -> int: """Change the stream position relative to start (0), current (1), or end (2).""" async def tell(self) -> int: """Return the current stream position.""" async def close(self) -> None: """Release underlying system handles or HTTP connections.""" async def chunks(self, chunk_size: int = 65536) -> AsyncIterator[bytes]: """Stream the file in custom-sized byte chunks.""" StorageMetadata An immutable dataclass containing metadata for a stored file, returned by backend stat calls. @dataclass(frozen=True) class StorageMetadata: name: str # Relative path key size: int = 0 # Size in bytes content_type: str = "application/octet-stream" etag: str = "" # SHA-256 or remote MD5 hash last_modified: datetime | None = None created_at: datetime | None = None metadata: dict[str, str] = field(default_factory=dict) storage_class: str = "" # e.g., "STANDARD", "GLACIER" def to_dict(self) -> dict[str, Any]: """Convert metadata values to a serialized dictionary.""" Storage Fault Hierarchy Errors thrown by storage providers are normalized under the "storage" fault domain. Fault Class Fault Code Description ))} )

### Code Examples
```python
class StorageRegistry:
    def __init__(self) -> None:
        """Create an empty storage registry."""

    @property
    def default(self) -> StorageBackend:
        """Get the default registered StorageBackend instance.
        
        Raises StorageConfigFault if no default backend is set.
        """

    def register(self, alias: str, backend: StorageBackend) -> None:
        """Register a backend instance with the given alias name."""

    def unregister(self, alias: str) -> None:
        """Unregister a backend by its alias name."""

    def set_default(self, alias: str) -> None:
        """Define which registered alias acts as the default backend."""

    def get(self, alias: str) -> StorageBackend | None:
        """Look up a backend instance by alias. Returns None if missing."""

    def __getitem__(self, alias: str) -> StorageBackend:
        """Access a backend via bracket notation registry[alias].
        
        Raises KeyError if alias is not found.
        """

    async def initialize_all(self) -> None:
        """Run the async initialize() lifecycle hook on all registered backends."""

    async def shutdown_all(self) -> None:
        """Close/release connections on all registered backends."""

    async def health_check(self) -> dict[str, bool]:
        """Runs a ping() check on each registered backend.
        
        Returns a dictionary of {alias: is_healthy}.
        """
```

```python
from abc import ABC, abstractmethod
from collections.abc import AsyncIterator
from typing import BinaryIO

class StorageBackend(ABC):
    @property
    @abstractmethod
    def backend_name(self) -> str:
        """Returns the driver name identifier (e.g. 'local', 's3')."""

    async def initialize(self) -> None:
        """Bootstrap directory structures, connections, or credential handshakes."""

    async def ping(self) -> bool:
        """Verifies driver accessibility. Returns True if healthy, False otherwise."""

    @abstractmethod
    async def save(
        self,
        name: str,
        content: bytes | BinaryIO | AsyncIterator[bytes] | StorageFile,
        *,
        content_type: str | None = None,
        metadata: dict[str, str] | None = None,
        overwrite: bool = False,
    ) -> str:
        """Save a file to the backend.
        
        Args:
            name: Path/key target.
            content: Raw byte content, file-like object, or async generator.
            content_type: MIME string (auto-detected if None).
            metadata: Custom tag key/values.
            overwrite: Replaces the file if True, otherwise appends an increments counter.

        Returns:
            The final saved relative path string.
        """

    @abstractmethod
    async def open(self, name: str, mode: str = "rb") -> StorageFile:
        """Open a file handle for reading or writing.
        
        Returns:
            A StorageFile wrapper.
        """

    @abstractmethod
    async def delete(self, name: str) -> None:
        """Deletes a file. Idempotent: does NOT raise if the file does not exist."""

    @abstractmethod
    async def exists(self, name: str) -> bool:
        """Returns True if the file exists, False otherwise."""

    @abstractmethod
    async def stat(self, name: str) -> StorageMetadata:
        """Returns metadata for the file. Raises FileNotFoundError if missing."""

    @abstractmethod
    async def listdir(self, path: str = "") -> tuple[list[str], list[str]]:
        """List subdirectories and files in a path.
        
        Returns:
            A tuple of (directories_list, files_list).
        """

    @abstractmethod
    async def size(self, name: str) -> int:
        """Returns the file size in bytes."""

    @abstractmethod
    async def url(self, name: str, expire: int | None = None) -> str:
        """Generates a public URL or signed temporary URL.
        
        Args:
            expire: URL expiration period in seconds.
        """
```

```python
class StorageFile:
    @property
    def closed(self) -> bool:
        """Returns True if the file has been closed."""

    async def read(self, size: int = -1) -> bytes:
        """Read up to size bytes. If -1, reads the entire file."""

    async def write(self, data: bytes) -> int:
        """Write bytes to the file (requires a writable open mode)."""

    async def seek(self, offset: int, whence: int = 0) -> int:
        """Change the stream position relative to start (0), current (1), or end (2)."""

    async def tell(self) -> int:
        """Return the current stream position."""

    async def close(self) -> None:
        """Release underlying system handles or HTTP connections."""

    async def chunks(self, chunk_size: int = 65536) -> AsyncIterator[bytes]:
        """Stream the file in custom-sized byte chunks."""
```



---

## Storage Configuration
**URL**: `https://tubox.cloud/docs/storage/configuration`

Unified Storage / Configuration Storage Configuration A complete guide to configuring unified storage backends inside your Aquilia workspace using typed configuration dataclasses. Integration Configuration Styles Aquilia supports two styles of declaring subsystem integrations within workspace.py: the legacy builder-class style and the modern typed-dataclass style. Modern Style: Composed Dataclasses (Recommended) Construct the StorageIntegration class directly. This ensures compile-time validation, IDE type hinting, and strict parameter checking. # workspace.py from aquilia import Workspace, Module from aquilia.integrations import StorageIntegration from aquilia.storage.configs import LocalConfig, S3Config workspace = ( Workspace("myapp") .module(Module("core")) .integrate(StorageIntegration( default="local", backends= )) ) Legacy Style: Static Integration Builders The legacy .storage() or Integration.storage() helper delegates to the modern StorageIntegration under the hood. Avoid this in new projects. # workspace.py (Legacy) from aquilia import Workspace from aquilia.storage import LocalConfig workspace = ( Workspace("myapp") .storage( default="local", backends= ) ) Warning: The legacy static helper .storage() is deprecated and will be removed in a future release. Migrate to direct constructor calls using StorageIntegration. Backend Configuration Options LocalConfig Configures the local disk backend. Inherits from StorageConfig. Attribute Type Default Description ))} MemoryConfig Configures ephemeral in-memory storage, useful for mocking disk I/O in test suites. Attribute Type Default Description ))} S3Config Configures AWS S3 and compatible storage layers. Attribute Type Default Description ))} CompositeConfig Configures composite storage to route calls dynamically to other backends. Attribute Type Default Description ', 'Sub-backend dictionary mappings.'], ['rules', 'dict', ' ', 'Glob patterns mapped to target backend aliases.'], ['fallback', 'str', '"default"', 'Alias to route requests to when no rules match.'], ].map(([attr, type, defVal, desc], i) => ( ))} Module Manifest & ComponentRef Instead of declaring component imports as bare string paths, Aquilia v2 recommends using the ComponentRef class inside manifest.py. This offers typed metadata checks during boot scans. # modules/uploads/manifest.py from aquilia import AppManifest, ComponentRef, ComponentKind manifest = AppManifest( name="uploads", controllers=[ # Controller component references ComponentRef( class_path="modules.uploads.controllers:FilesController", kind=ComponentKind.CONTROLLER ) ], services=[] ) )

### Code Examples
```python
# workspace.py
from aquilia import Workspace, Module
from aquilia.integrations import StorageIntegration
from aquilia.storage.configs import LocalConfig, S3Config

workspace = (
    Workspace("myapp")
    .module(Module("core"))
    .integrate(StorageIntegration(
        default="local",
        backends={
            "local": LocalConfig(
                root="./uploads",
                base_url="/static/uploads/",
                permissions=0o644,
                dir_permissions=0o755,
                create_dirs=True
            ),
            "s3": S3Config(
                bucket="my-production-bucket",
                region="us-east-1",
                prefix="media/",
                presigned_expiry=3600
            )
        }
    ))
)
```

```python
# workspace.py (Legacy)
from aquilia import Workspace
from aquilia.storage import LocalConfig

workspace = (
    Workspace("myapp")
    .storage(
        default="local",
        backends={
            "local": LocalConfig(root="./storage")
        }
    )
)
```

```python
# modules/uploads/manifest.py
from aquilia import AppManifest, ComponentRef, ComponentKind

manifest = AppManifest(
    name="uploads",
    controllers=[
        # Controller component references
        ComponentRef(
            class_path="modules.uploads.controllers:FilesController",
            kind=ComponentKind.CONTROLLER
        )
    ],
    services=[]
)
```



---

## Backend Setup Guide
**URL**: `https://tubox.cloud/docs/storage/backends`

Storage / Backend Setup Backend Setup Guide A complete walkthrough for setting up local, in-memory, AWS S3, Google Cloud, Azure Blob, SFTP, and Composite storage drivers. Local Filesystem Storage Stores files directly in a directory on the local machine. It is pre-installed in the core package and requires no external libraries. Workspace Configuration # workspace.py from aquilia import Workspace from aquilia.storage import LocalConfig workspace = ( Workspace("myapp") .storage( default="local", backends= ) ) Standalone Programmatic Setup from aquilia.storage.backends import LocalStorage from aquilia.storage.configs import LocalConfig config = LocalConfig(root="./storage", create_dirs=True) storage = LocalStorage(config) await storage.initialize() await storage.save("notes.txt", b"Local storage active") Amazon S3 & S3-Compatible Storage Connects to AWS S3, MinIO, Cloudflare R2, or DigitalOcean Spaces. Offloads blocking I/O to a background thread pool. 1. Install Dependencies pip install boto3 2. Workspace Configuration # workspace.py from aquilia import Workspace from aquilia.storage import S3Config workspace = ( Workspace("myapp") .storage( default="s3", backends= ) ) 3. Manual Credentials Override from aquilia.storage.backends import S3Storage from aquilia.storage.configs import S3Config storage = S3Storage(S3Config( bucket="my-app-assets", region="us-east-1", access_key="ACCESS_KEY_ID", secret_key="SECRET_ACCESS_KEY", endpoint_url="https://minio.mycompany.internal", # Override for MinIO )) Google Cloud Storage (GCS) Integrates with Google Cloud Storage buckets. 1. Install Dependencies pip install google-cloud-storage 2. Workspace Configuration # workspace.py from aquilia import Workspace from aquilia.storage import GCSConfig workspace = ( Workspace("myapp") .storage( default="gcs", backends= ) ) Azure Blob Storage Integrates with Azure Blob Storage containers. 1. Install Dependencies pip install azure-storage-blob 2. Workspace Configuration # workspace.py from aquilia import Workspace from aquilia.storage import AzureBlobConfig workspace = ( Workspace("myapp") .storage( default="azure", backends= ) ) SFTP / SSH Storage Saves and retrieves files over SFTP. 1. Install Dependencies pip install paramiko 2. Workspace Configuration # workspace.py from aquilia import Workspace from aquilia.storage import SFTPConfig workspace = ( Workspace("myapp") .storage( default="sftp", backends= ) ) Composite Storage Routing A composite backend delegates read/write requests to other registered backends based on glob patterns matched against the file path. # workspace.py from aquilia import Workspace from aquilia.storage import CompositeConfig, LocalConfig, S3Config workspace = ( Workspace("myapp") .storage( default="composite", backends= , "cloud_s3": , }, # Setup routing rules (glob pattern -> backend alias name) rules= , fallback="local_cache", # Fallback alias if no rules match ) } ) ) )

### Code Examples
```python
# workspace.py
from aquilia import Workspace
from aquilia.storage import LocalConfig

workspace = (
    Workspace("myapp")
    .storage(
        default="local",
        backends={
            "local": LocalConfig(
                root="./uploads",
                base_url="/static/uploads/",
                permissions=0o644,
                create_dirs=True
            )
        }
    )
)
```

```python
from aquilia.storage.backends import LocalStorage
from aquilia.storage.configs import LocalConfig

config = LocalConfig(root="./storage", create_dirs=True)
storage = LocalStorage(config)
await storage.initialize()

await storage.save("notes.txt", b"Local storage active")
```

```python
pip install boto3
```



---

## async SQLite Module
**URL**: `https://tubox.cloud/docs/sqlite`

SQLite Module / Overview async SQLite Module Aquilia provides a zero-dependency, native async SQLite connection pool wrapper that makes standard library sqlite3 async-safe by offloading blocking operations to a dedicated thread pool. Quick Start Instantiate the connection pool using create_pool() and a SqlitePoolConfig or a DB URL string. from aquilia.sqlite import create_pool, SqlitePoolConfig # Option A: Simple connection URL (uses WAL mode and default pool settings) pool = await create_pool("sqlite:///app.db") # Option B: Advanced configuration via SqlitePoolConfig config = SqlitePoolConfig( path="app.db", pool_size=10, # Number of concurrent reader connections journal_mode="WAL", # Write-Ahead Logging synchronous="NORMAL", # Optimal WAL speed/durability trade-off ) pool = await create_pool(config) # Quick execution (uses connection pool direct helpers) await pool.execute( "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)" ) await pool.execute( "INSERT INTO items (name) VALUES (?)", ["Product A"] ) # Fetching rows (returns dict-like Row objects) rows = await pool.fetch_all("SELECT * FROM items") for row in rows: print(f"ID: | Name: ") Workspace Configuration Styles Aquilia support both the legacy static builder integration style and the modern typed-dataclass style inside workspace.py: Modern Style: DatabaseIntegration Dataclass (Recommended) Directly integrate the typed DatabaseIntegration configuration: # workspace.py from aquilia import Workspace from aquilia.integrations import DatabaseIntegration workspace = ( Workspace("myapp") .integrate(DatabaseIntegration( url="sqlite:///app.db", pool_size=8, journal_mode="WAL", synchronous="NORMAL" )) ) Legacy Style: Static Database Builder The legacy static Integration.database() or .database() method: # workspace.py (Legacy) from aquilia import Workspace from aquilia.integrations import Integration workspace = ( Workspace("myapp") .database(url="sqlite:///app.db") ) Warning: The legacy static helper .database() is deprecated and will be removed in a future release. Migrate to direct constructor calls using DatabaseIntegration. Subsystem Features ))} Pool Concurrency Architecture Aquilia's connection pool maintains N reader connections plus exactly 1 writer connection. This matches SQLite's single-writer limitation while allowing concurrent reads in Write-Ahead Log (WAL) mode. CONNECTIONPOOL WAL Concurrency Mode READER POOL N read-only connections Semaphore protected reader_0, reader_1, ... reader_N SERIALIZED WRITER 1 read-write connection asyncio.Lock protected writer_connection (exclusive write) )

### Code Examples
```python
from aquilia.sqlite import create_pool, SqlitePoolConfig

# Option A: Simple connection URL (uses WAL mode and default pool settings)
pool = await create_pool("sqlite:///app.db")

# Option B: Advanced configuration via SqlitePoolConfig
config = SqlitePoolConfig(
    path="app.db",
    pool_size=10,             # Number of concurrent reader connections
    journal_mode="WAL",       # Write-Ahead Logging
    synchronous="NORMAL",     # Optimal WAL speed/durability trade-off
)
pool = await create_pool(config)

# Quick execution (uses connection pool direct helpers)
await pool.execute(
    "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)"
)
await pool.execute(
    "INSERT INTO items (name) VALUES (?)", ["Product A"]
)

# Fetching rows (returns dict-like Row objects)
rows = await pool.fetch_all("SELECT * FROM items")
for row in rows:
    print(f"ID: {row.id} | Name: {row['name']}")
```

```python
# workspace.py
from aquilia import Workspace
from aquilia.integrations import DatabaseIntegration

workspace = (
    Workspace("myapp")
    .integrate(DatabaseIntegration(
        url="sqlite:///app.db",
        pool_size=8,
        journal_mode="WAL",
        synchronous="NORMAL"
    ))
)
```

```python
# workspace.py (Legacy)
from aquilia import Workspace
from aquilia.integrations import Integration

workspace = (
    Workspace("myapp")
    .database(url="sqlite:///app.db")
)
```



---

## SQLite API Reference
**URL**: `https://tubox.cloud/docs/sqlite/api`

SQLite / API Reference SQLite API Reference Detailed interface specifications for SQLite pools, connections, row objects, prepared statement caches, and query methods. Table of Contents , , , , , , ].map((item, i) => ( • ))} create_pool() Initialize a connection pool for the SQLite database. from aquilia.sqlite import create_pool, SqlitePoolConfig async def create_pool( config: SqlitePoolConfig | str, metrics: SqliteMetrics | None = None, ) -> ConnectionPool ConnectionPool Manages reader and writer connections, exposing shortcuts for query execution. class ConnectionPool: def acquire(self, *, readonly: bool = False) -> _AcquireContext: """Acquire a connection from the pool. Returns a context manager yielding AsyncConnection. """ async def close(self) -> None: """Close all connections inside the pool.""" async def execute( self, sql: str, params: Sequence[Any] | None = None, ) -> AsyncCursor: """Helper to acquire writer connection and execute SQL statement.""" async def execute_many( self, sql: str, params_seq: Sequence[Sequence[Any]], ) -> int: """Helper to execute SQL across multiple parameter sets. Returns affected rowcount.""" async def fetch_all( self, sql: str, params: Sequence[Any] | None = None, ) -> list[Row]: """Helper to acquire reader connection and fetch all rows.""" async def fetch_one( self, sql: str, params: Sequence[Any] | None = None, ) -> Row | None: """Helper to acquire reader connection and fetch a single row.""" async def fetch_val( self, sql: str, params: Sequence[Any] | None = None, *, column: int = 0, ) -> Any: """Helper to fetch a single scalar value from the first row.""" AsyncConnection Wraps a single connection, mapping query and transaction calls to thread pool execution. class AsyncConnection: @property def readonly(self) -> bool: """Returns True if this is a read-only reader connection.""" @property def in_transaction(self) -> bool: """Returns True if a transaction is currently active.""" async def execute(self, sql: str, params: Sequence[Any] | None = None) -> AsyncCursor: """Execute a single SQL statement.""" async def execute_many(self, sql: str, params_seq: Sequence[Sequence[Any]]) -> int: """Execute SQL with multiple parameter sets.""" async def fetch_all(self, sql: str, params: Sequence[Any] | None = None) -> list[Row]: """Fetch all rows.""" async def fetch_one(self, sql: str, params: Sequence[Any] | None = None) -> Row | None: """Fetch a single row or None.""" async def fetch_val(self, sql: str, params: Sequence[Any] | None = None, *, column: int = 0) -> Any: """Fetch a single scalar value.""" def transaction(self, *, mode: str = "DEFERRED") -> TransactionContext: """Returns a transaction context manager (DEFERRED, IMMEDIATE, EXCLUSIVE).""" def savepoint_ctx(self, name: str) -> SavepointContext: """Returns a savepoint context manager.""" async def table_exists(self, name: str) -> bool: """Returns True if the table exists.""" async def get_tables(self) -> list[str]: """List all user-defined table names.""" async def backup(self, target: str | AsyncConnection, *, pages: int = -1) -> None: """Perform an online backup to another file or connection.""" Row High-performance, dict-like object wrapping SQLite rows. class Row: def keys(self) -> list[str]: """Get list of column names.""" def values(self) -> list[Any]: """Get list of column values.""" def items(self) -> list[tuple[str, Any]]: """Get list of (column, value) tuples.""" def __getitem__(self, key: int | str) -> Any: """Get column value by integer index or name string.""" def __getattr__(self, name: str) -> Any: """Access column value via attribute name.""" SqlitePoolConfig Configuration dataclass for native SQLite connection pools. @dataclass class SqlitePoolConfig: path: str = "db.sqlite3" journal_mode: str = "WAL" foreign_keys: bool = True busy_timeout: int = 5000 # milliseconds synchronous: str = "NORMAL" cache_size: int = -8000 # negative = KiB mmap_size: int = 268435456 # bytes (256 MB) temp_store: str = "MEMORY" pool_size: int = 5 # reader connections count pool_min_size: int = 2 statement_cache_size: int = 256 query_timeout: float = 30.0 # seconds echo: bool = False auto_commit: bool = True SQLite Error Hierarchy Custom exceptions raised by the native wrapper. Exception Class Base Class Description ))} )

### Code Examples
```python
from aquilia.sqlite import create_pool, SqlitePoolConfig

async def create_pool(
    config: SqlitePoolConfig | str,
    metrics: SqliteMetrics | None = None,
) -> ConnectionPool
```

```python
class ConnectionPool:
    def acquire(self, *, readonly: bool = False) -> _AcquireContext:
        """Acquire a connection from the pool.
        
        Returns a context manager yielding AsyncConnection.
        """

    async def close(self) -> None:
        """Close all connections inside the pool."""

    async def execute(
        self,
        sql: str,
        params: Sequence[Any] | None = None,
    ) -> AsyncCursor:
        """Helper to acquire writer connection and execute SQL statement."""

    async def execute_many(
        self,
        sql: str,
        params_seq: Sequence[Sequence[Any]],
    ) -> int:
        """Helper to execute SQL across multiple parameter sets. Returns affected rowcount."""

    async def fetch_all(
        self,
        sql: str,
        params: Sequence[Any] | None = None,
    ) -> list[Row]:
        """Helper to acquire reader connection and fetch all rows."""

    async def fetch_one(
        self,
        sql: str,
        params: Sequence[Any] | None = None,
    ) -> Row | None:
        """Helper to acquire reader connection and fetch a single row."""

    async def fetch_val(
        self,
        sql: str,
        params: Sequence[Any] | None = None,
        *,
        column: int = 0,
    ) -> Any:
        """Helper to fetch a single scalar value from the first row."""
```

```python
class AsyncConnection:
    @property
    def readonly(self) -> bool:
        """Returns True if this is a read-only reader connection."""

    @property
    def in_transaction(self) -> bool:
        """Returns True if a transaction is currently active."""

    async def execute(self, sql: str, params: Sequence[Any] | None = None) -> AsyncCursor:
        """Execute a single SQL statement."""

    async def execute_many(self, sql: str, params_seq: Sequence[Sequence[Any]]) -> int:
        """Execute SQL with multiple parameter sets."""

    async def fetch_all(self, sql: str, params: Sequence[Any] | None = None) -> list[Row]:
        """Fetch all rows."""

    async def fetch_one(self, sql: str, params: Sequence[Any] | None = None) -> Row | None:
        """Fetch a single row or None."""

    async def fetch_val(self, sql: str, params: Sequence[Any] | None = None, *, column: int = 0) -> Any:
        """Fetch a single scalar value."""

    def transaction(self, *, mode: str = "DEFERRED") -> TransactionContext:
        """Returns a transaction context manager (DEFERRED, IMMEDIATE, EXCLUSIVE)."""

    def savepoint_ctx(self, name: str) -> SavepointContext:
        """Returns a savepoint context manager."""

    async def table_exists(self, name: str) -> bool:
        """Returns True if the table exists."""

    async def get_tables(self) -> list[str]:
        """List all user-defined table names."""

    async def backup(self, target: str | AsyncConnection, *, pages: int = -1) -> None:
        """Perform an online backup to another file or connection."""
```



---

## Pool Configuration
**URL**: `https://tubox.cloud/docs/sqlite/pool`

SQLite / Pool Configuration Pool Configuration Fine-tune the SQLite connection pool settings, sizing limits, PRAGMA parameters, and statement caches for production workloads. Configuring via SqlitePoolConfig All connection pool settings are configured via the SqlitePoolConfig dataclass, which is passed to create_pool() . from aquilia.sqlite import create_pool, SqlitePoolConfig config = SqlitePoolConfig( path="app.db", # Pool sizing & timeouts pool_size=10, # Number of concurrent reader connections pool_min_size=4, # Pre-opened reader connections pool_timeout=30.0, # Wait limit to acquire connection (seconds) pool_max_idle_time=300.0, # Eviction time for idle connections (seconds) # Cache settings cache_size=-16000, # Negative = KiB (16MB memory cache) statement_cache_size=256, # Max cached prepared statements per connection ) pool = await create_pool(config) SQLite Journal Modes Controls how SQLite handles transaction logs on disk. WAL mode is highly recommended as it enables multi-reader concurrency. Journal Mode Description Concurrency Level ))} Synchronous Disk Flushing Determines how aggressively SQLite forces disk syncs (fsync). When using WAL mode, NORMAL is recommended. Sync Mode Disk Flushing Safety Level ))} Performance Optimization Settings Memory-Mapped I/O (mmap_size) Memory-mapping maps database pages directly into host process RAM, bypassing system call read paths. Highly recommended for read-heavy databases. # Enable 256MB memory mapping config = SqlitePoolConfig(mmap_size=268435456) Warning: Set mmap_size=0 for databases that are extremely write-heavy to prevent memory thrashing. Statement Cache (statement_cache_size) Caches prepared SQL queries to eliminate SQL parsing overhead on subsequent executions. # Cache 256 prepared statements per connection config = SqlitePoolConfig(statement_cache_size=256) Uptime & Performance Metrics Inspect connection pool allocations and statements caching hits: # Inspect active connection counters print(f"Total Queries: ") print(f"Active Reader Connections: ") print(f"Average Query Duration: ms") # Inspect statement cache efficiency stats print(f"Prepared Cache Hits: ") print(f"Prepared Cache Misses: ") print(f"Hit Rate Percent: %") )

### Code Examples
```python
from aquilia.sqlite import create_pool, SqlitePoolConfig

config = SqlitePoolConfig(
    path="app.db",
    
    # Pool sizing & timeouts
    pool_size=10,                 # Number of concurrent reader connections
    pool_min_size=4,              # Pre-opened reader connections
    pool_timeout=30.0,            # Wait limit to acquire connection (seconds)
    pool_max_idle_time=300.0,     # Eviction time for idle connections (seconds)
    
    # Cache settings
    cache_size=-16000,            # Negative = KiB (16MB memory cache)
    statement_cache_size=256,     # Max cached prepared statements per connection
)

pool = await create_pool(config)
```

```python
# Enable 256MB memory mapping
config = SqlitePoolConfig(mmap_size=268435456)
```

```python
# Cache 256 prepared statements per connection
config = SqlitePoolConfig(statement_cache_size=256)
```



---

## Transactions & Savepoints
**URL**: `https://tubox.cloud/docs/sqlite/transactions`

SQLite / Transactions & Savepoints Transactions & Savepoints Execute atomic block queries with automatic transaction rollbacks and nested savepoints. Basic Transactions Use the transaction() context manager of a connection to run multiple queries atomically. By default, transactions run in DEFERRED mode. async with pool.acquire(readonly=False) as conn: async with conn.transaction(): # Both inserts succeed together, or both are rolled back on error await conn.execute( "INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"] ) await conn.execute( "INSERT INTO settings (user_name, theme) VALUES (?, ?)", ["Alice", "dark"] ) Auto-Commit / Auto-Rollback: The transaction is committed automatically when exiting the context block without exceptions. If an unhandled exception occurs inside the block, the transaction is rolled back immediately. Savepoints (Nested Transactions) SQLite does not support nested transactions natively. However, Aquilia provides savepoint_ctx() to implement nested transaction boundaries that rollback partial work without rolling back the entire parent transaction. async with pool.acquire(readonly=False) as conn: async with conn.transaction() as parent_txn: # Parent insertion await conn.execute("INSERT INTO logs (message) VALUES (?)", ["Initial Log"]) try: # Nested savepoint context async with conn.savepoint_ctx("sp1"): await conn.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]) raise ValueError("Rollback Bob insertion") except ValueError: # Bob insertion is rolled back, parent logs are preserved pass await conn.execute("INSERT INTO logs (message) VALUES (?)", ["Execution Finished"]) Transaction Locking Modes Control when lock acquisitions are obtained on the database file. Configure via the mode argument on transaction(). Lock Mode Lock Acquisition Typical Use Case ))} Read-Only Connections Maximize WAL concurrency by explicitly acquiring read-only connections. The pool routes read queries to the parallel reader pool when readonly=True is passed. # Acquire a read-only reader connection (does not block the writer connection) async with pool.acquire(readonly=True) as conn: rows = await conn.fetch_all("SELECT * FROM users WHERE active = 1") Common Pitfalls 1. Nested Transaction Calls Calling nested conn.transaction() blocks within each other raises an error. Always use savepoint contexts for nesting. # BAD - Will raise error async with conn.transaction(): async with conn.transaction(): # Raises TransactionFault pass # GOOD - Use savepoint contexts async with conn.transaction(): async with conn.savepoint_ctx("sp_checkpoint"): pass 2. Network I/O Inside Transactions Since SQLite serialization restricts concurrent writes, holding a transaction open while executing slow HTTP requests blocks other writers. # BAD - Blocks the single database writer connection async with conn.transaction(): await conn.execute("UPDATE users SET processing = 1 WHERE id = ?", [user_id]) await call_third_party_api() # Network call blocks connection pool await conn.execute("UPDATE users SET processed = 1 WHERE id = ?", [user_id]) # GOOD - Keep transaction blocks brief await conn.execute("UPDATE users SET processing = 1 WHERE id = ?", [user_id]) await call_third_party_api() async with conn.transaction(): await conn.execute("UPDATE users SET processed = 1 WHERE id = ?", [user_id]) )

### Code Examples
```python
async with pool.acquire(readonly=False) as conn:
    async with conn.transaction():
        # Both inserts succeed together, or both are rolled back on error
        await conn.execute(
            "INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"]
        )
        await conn.execute(
            "INSERT INTO settings (user_name, theme) VALUES (?, ?)", ["Alice", "dark"]
        )
```

```python
async with pool.acquire(readonly=False) as conn:
    async with conn.transaction() as parent_txn:
        # Parent insertion
        await conn.execute("INSERT INTO logs (message) VALUES (?)", ["Initial Log"])
        
        try:
            # Nested savepoint context
            async with conn.savepoint_ctx("sp1"):
                await conn.execute("INSERT INTO users (name) VALUES (?)", ["Bob"])
                raise ValueError("Rollback Bob insertion")
        except ValueError:
            # Bob insertion is rolled back, parent logs are preserved
            pass
            
        await conn.execute("INSERT INTO logs (message) VALUES (?)", ["Execution Finished"])
```

```python
# Acquire a read-only reader connection (does not block the writer connection)
async with pool.acquire(readonly=True) as conn:
    rows = await conn.fetch_all("SELECT * FROM users WHERE active = 1")
```



---

## Filesystem Module
**URL**: `https://tubox.cloud/docs/filesystem`

Filesystem Filesystem Module High-performance native async file I/O. A drop-in replacement for aiofiles that uses thread pool execution with atomic writes, streaming, and built-in security. Quick Example from aquilia.filesystem import FileSystem, async_open, read_file, write_file # Simple file operations content = await read_file("config.json") await write_file("output.txt", "Hello, World!") # Async file handle async with await async_open("data.csv", "r") as f: async for line in f: process(line) # Using FileSystem service (DI-injectable) fs = FileSystem() files = await fs.list_dir("./logs") for file in files: stats = await fs.stat(file) print(f" : bytes") Key Features ))} API Overview The module provides standalone functions and a FileSystem service class: Function Description ) })} Atomic Writes By default, write_file() performs atomic writes to prevent data corruption: # This is safe even if the process crashes mid-write await write_file("config.json", new_config) # How it works internally: # 1. Write to temp file: config.json.tmp.abc123 # 2. Sync to disk (fsync) # 3. Atomic rename: config.json.tmp.abc123 → config.json # Result: Either old or new content, never partial # Disable atomic writes if needed (not recommended) await write_file("log.txt", data, atomic=False) Why this matters: Without atomic writes, a crash during write can leave a file with partial content (truncated or mixed old/new data). Atomic writes guarantee the file is always in a consistent state. Security Features All path operations are automatically validated for security at the lowest layer: Path Traversal Protection Strict validation rejects any paths containing parent traversal patterns (e.g., ..) to keep file reads sandboxed. Null Byte Rejection Detects and raises a fault on C-style null bytes (\x00) to prevent extension spoofing and file truncation exploits. Path Length Limits Applies length constraints on inputs (defaulting to 4096 characters) to stop denial of service buffer overflow attempts. Filename Sanitization The sanitize_filename() utility strips dangerous control tags and symbols to sanitize client uploads. from aquilia.filesystem import read_file, validate_path, sanitize_filename from aquilia.filesystem import PathTraversalFault # These will raise PathTraversalFault: await read_file("../../../etc/passwd") # Traversal attack await read_file("file\\x00name.txt") # Null byte injection # Use validate_path for manual checking try: validate_path(user_provided_path) except PathTraversalFault: raise HTTPException(400, "Invalid path") # Sanitize user-provided filenames safe_name = sanitize_filename("my../file\\x00.txt") # "my_file_.txt" AsyncFile Handle For more control, use async_open() to get an async file handle: from aquilia.filesystem import async_open # Read mode async with await async_open("data.txt", "r") as f: content = await f.read() # Read all first_line = await f.readline() # Read one line lines = await f.readlines() # Read all lines # Write mode async with await async_open("output.txt", "w") as f: await f.write("Hello, ") await f.write("World!\\n") await f.writelines(["Line 1\\n", "Line 2\\n"]) # Binary mode async with await async_open("image.png", "rb") as f: data = await f.read() # Streaming iteration async with await async_open("large.csv", "r") as f: async for line in f: process_line(line) Why Not aiofiles? Feature aquilia.filesystem aiofiles ))} Installation The filesystem module is included in the core Aquilia package. No additional dependencies required. pip install aquilia # That's it! No additional packages needed. )

### Code Examples
```python
from aquilia.filesystem import FileSystem, async_open, read_file, write_file

# Simple file operations
content = await read_file("config.json")
await write_file("output.txt", "Hello, World!")

# Async file handle
async with await async_open("data.csv", "r") as f:
    async for line in f:
        process(line)

# Using FileSystem service (DI-injectable)
fs = FileSystem()
files = await fs.list_dir("./logs")
for file in files:
    stats = await fs.stat(file)
    print(f"{file}: {stats.size} bytes")
```

```python
# This is safe even if the process crashes mid-write
await write_file("config.json", new_config)

# How it works internally:
# 1. Write to temp file: config.json.tmp.abc123
# 2. Sync to disk (fsync)
# 3. Atomic rename: config.json.tmp.abc123 → config.json
# Result: Either old or new content, never partial

# Disable atomic writes if needed (not recommended)
await write_file("log.txt", data, atomic=False)
```

```python
from aquilia.filesystem import read_file, validate_path, sanitize_filename
from aquilia.filesystem import PathTraversalFault

# These will raise PathTraversalFault:
await read_file("../../../etc/passwd")  # Traversal attack
await read_file("file\\x00name.txt")     # Null byte injection

# Use validate_path for manual checking
try:
    validate_path(user_provided_path)
except PathTraversalFault:
    raise HTTPException(400, "Invalid path")

# Sanitize user-provided filenames
safe_name = sanitize_filename("my../file\\x00.txt")  # "my_file_.txt"
```



---

## Filesystem API Reference
**URL**: `https://tubox.cloud/docs/filesystem/api`

Filesystem / API Reference Filesystem API Reference Detailed interface specifications for standalone async file operations, context-managed file handles, and directory path wrappers. Table of Contents , , , , , ].map((item, i) => ( • ))} Core Helper Functions High-level standalone functions available directly under aquilia.filesystem. from aquilia.filesystem import async_open, read_file, write_file async def async_open( path: str | Path, mode: str = "r", encoding: str | None = None, errors: str | None = None, buffering: int = -1, newline: str | None = None, ) -> AsyncFile: """Opens a file asynchronously. Yields an AsyncFile context manager.""" async def read_file( path: str | Path, encoding: str = "utf-8", errors: str = "strict", ) -> str | bytes: """Read and return entire file content. Returns bytes if binary mode is requested.""" async def write_file( path: str | Path, data: str | bytes, encoding: str = "utf-8", errors: str = "strict", atomic: bool = True, # Uses temp file + rename if True make_parents: bool = True, # Auto-creates parent directories ) -> None: """Writes content to a file.""" async def append_file( path: str | Path, data: str | bytes, encoding: str = "utf-8", errors: str = "strict", ) -> None: """Appends data to the end of a file.""" async def copy_file(src: str | Path, dst: str | Path) -> None: """Copy a file from source to destination.""" async def move_file(src: str | Path, dst: str | Path) -> None: """Move/rename a file atomically.""" async def delete_file(path: str | Path) -> None: """Delete a file. Idempotent: does NOT raise if file is missing.""" async def file_exists(path: str | Path) -> bool: """Returns True if the path exists and is a file.""" async def file_stat(path: str | Path) -> os.stat_result: """Retrieve file metadata (size, last modified time, etc.).""" FileSystem The DI-managed filesystem service class containing all query and operation methods. class FileSystem: def __init__(self, config: FileSystemConfig | None = None) -> None: """Create a new FileSystem service wrapper.""" async def open(self, path: str | Path, mode: str = "r", **kwargs: Any) -> AsyncFile: """Alias for async_open.""" async def read(self, path: str | Path, **kwargs: Any) -> str | bytes: """Alias for read_file.""" async def write(self, path: str | Path, data: str | bytes, **kwargs: Any) -> None: """Alias for write_file.""" async def list_dir(self, path: str | Path) -> list[str]: """List all filenames and subdirectories in a directory path.""" async def scan_dir(self, path: str | Path) -> AsyncIterator[DirEntry]: """Asynchronously iterate over entries (files/directories) in a path.""" async def make_dir(self, path: str | Path, parents: bool = True, exist_ok: bool = True) -> None: """Create a new directory.""" async def remove_dir(self, path: str | Path) -> None: """Remove an empty directory.""" async def remove_tree(self, path: str | Path) -> None: """Delete a directory and all of its contents recursively.""" async def copy_tree(self, src: str | Path, dst: str | Path) -> None: """Copy a directory tree recursively to another destination.""" def walk( self, top: str | Path, top_down: bool = True, on_error: Callable[[OSError], Any] | None = None, follow_symlinks: bool = False, ) -> AsyncIterator[tuple[str, list[str], list[str]]]: """Asynchronously walk a directory tree yielding (dirpath, dirnames, filenames).""" AsyncFile An asynchronous file handle wrapping a native file object, offering non-blocking reads and writes. class AsyncFile: @property def name(self) -> str: """The file path.""" @property def mode(self) -> str: """The open mode.""" @property def closed(self) -> bool: """Returns True if the file has been closed.""" @property def encoding(self) -> str | None: """File encoding (None for binary files).""" async def read(self, size: int = -1) -> bytes | str: """Read up to size bytes/characters. Reads all if size=-1.""" async def readline(self) -> bytes | str: """Read a single line.""" async def readlines(self) -> list[bytes | str]: """Read all lines into a list.""" async def readinto(self, buffer: bytearray) -> int: """Read bytes into a pre-allocated buffer (binary mode only).""" async def write(self, data: bytes | str) -> int: """Write data to the file.""" async def writelines(self, lines: Iterable[bytes | str]) -> None: """Write an iterable of lines.""" async def seek(self, offset: int, whence: int = 0) -> int: """Change the stream position.""" async def tell(self) -> int: """Return the current stream position.""" async def truncate(self, size: int | None = None) -> int: """Truncate the file to at most size bytes.""" async def flush(self) -> None: """Flush write buffer to disk.""" async def close(self) -> None: """Flush write buffers and close the file handle.""" AsyncPath An asynchronous object-oriented path class wrapper providing pathlib-style methods. class AsyncPath: def __init__(self, *args: str | Path | AsyncPath, **kwargs: Any) -> None @property def name(self) -> str: ... @property def stem(self) -> str: ... @property def suffix(self) -> str: ... @property def parent(self) -> AsyncPath: ... async def exists(self) -> bool: ... async def is_file(self) -> bool: ... async def is_dir(self) -> bool: ... async def stat(self) -> os.stat_result: ... async def mkdir(self, parents: bool = True, exist_ok: bool = True) -> None: ... async def rmdir(self) -> None: ... async def unlink(self, missing_ok: bool = False) -> None: ... async def open(self, mode: str = "r", **kwargs: Any) -> AsyncFile: ... async def read_text(self, encoding: str = "utf-8") -> str: ... async def write_text(self, data: str, encoding: str = "utf-8") -> None: ... async def read_bytes(self) -> bytes: ... async def write_bytes(self, data: bytes) -> None: ... Filesystem Fault Hierarchy Exception faults raised by the async filesystem module under the io domain. Fault Class Fault Code Description ))} )

### Code Examples
```python
from aquilia.filesystem import async_open, read_file, write_file

async def async_open(
    path: str | Path,
    mode: str = "r",
    encoding: str | None = None,
    errors: str | None = None,
    buffering: int = -1,
    newline: str | None = None,
) -> AsyncFile:
    """Opens a file asynchronously. Yields an AsyncFile context manager."""

async def read_file(
    path: str | Path,
    encoding: str = "utf-8",
    errors: str = "strict",
) -> str | bytes:
    """Read and return entire file content. Returns bytes if binary mode is requested."""

async def write_file(
    path: str | Path,
    data: str | bytes,
    encoding: str = "utf-8",
    errors: str = "strict",
    atomic: bool = True,           # Uses temp file + rename if True
    make_parents: bool = True,     # Auto-creates parent directories
) -> None:
    """Writes content to a file."""

async def append_file(
    path: str | Path,
    data: str | bytes,
    encoding: str = "utf-8",
    errors: str = "strict",
) -> None:
    """Appends data to the end of a file."""

async def copy_file(src: str | Path, dst: str | Path) -> None:
    """Copy a file from source to destination."""

async def move_file(src: str | Path, dst: str | Path) -> None:
    """Move/rename a file atomically."""

async def delete_file(path: str | Path) -> None:
    """Delete a file. Idempotent: does NOT raise if file is missing."""

async def file_exists(path: str | Path) -> bool:
    """Returns True if the path exists and is a file."""

async def file_stat(path: str | Path) -> os.stat_result:
    """Retrieve file metadata (size, last modified time, etc.)."""
```

```python
class FileSystem:
    def __init__(self, config: FileSystemConfig | None = None) -> None:
        """Create a new FileSystem service wrapper."""

    async def open(self, path: str | Path, mode: str = "r", **kwargs: Any) -> AsyncFile:
        """Alias for async_open."""

    async def read(self, path: str | Path, **kwargs: Any) -> str | bytes:
        """Alias for read_file."""

    async def write(self, path: str | Path, data: str | bytes, **kwargs: Any) -> None:
        """Alias for write_file."""

    async def list_dir(self, path: str | Path) -> list[str]:
        """List all filenames and subdirectories in a directory path."""

    async def scan_dir(self, path: str | Path) -> AsyncIterator[DirEntry]:
        """Asynchronously iterate over entries (files/directories) in a path."""

    async def make_dir(self, path: str | Path, parents: bool = True, exist_ok: bool = True) -> None:
        """Create a new directory."""

    async def remove_dir(self, path: str | Path) -> None:
        """Remove an empty directory."""

    async def remove_tree(self, path: str | Path) -> None:
        """Delete a directory and all of its contents recursively."""

    async def copy_tree(self, src: str | Path, dst: str | Path) -> None:
        """Copy a directory tree recursively to another destination."""

    def walk(
        self,
        top: str | Path,
        top_down: bool = True,
        on_error: Callable[[OSError], Any] | None = None,
        follow_symlinks: bool = False,
    ) -> AsyncIterator[tuple[str, list[str], list[str]]]:
        """Asynchronously walk a directory tree yielding (dirpath, dirnames, filenames)."""
```

```python
class AsyncFile:
    @property
    def name(self) -> str:
        """The file path."""

    @property
    def mode(self) -> str:
        """The open mode."""

    @property
    def closed(self) -> bool:
        """Returns True if the file has been closed."""

    @property
    def encoding(self) -> str | None:
        """File encoding (None for binary files)."""

    async def read(self, size: int = -1) -> bytes | str:
        """Read up to size bytes/characters. Reads all if size=-1."""

    async def readline(self) -> bytes | str:
        """Read a single line."""

    async def readlines(self) -> list[bytes | str]:
        """Read all lines into a list."""

    async def readinto(self, buffer: bytearray) -> int:
        """Read bytes into a pre-allocated buffer (binary mode only)."""

    async def write(self, data: bytes | str) -> int:
        """Write data to the file."""

    async def writelines(self, lines: Iterable[bytes | str]) -> None:
        """Write an iterable of lines."""

    async def seek(self, offset: int, whence: int = 0) -> int:
        """Change the stream position."""

    async def tell(self) -> int:
        """Return the current stream position."""

    async def truncate(self, size: int | None = None) -> int:
        """Truncate the file to at most size bytes."""

    async def flush(self) -> None:
        """Flush write buffer to disk."""

    async def close(self) -> None:
        """Flush write buffers and close the file handle."""
```



---

## File & Directory Operations
**URL**: `https://tubox.cloud/docs/filesystem/operations`

Filesystem / Guide File & Directory Operations A comprehensive guide to managing files, directory structures, streaming chunks, path globbing, and atomic operations. Directory Management Listing Directory Contents (list_dir) Acquires listing array of filenames (names only, not absolute paths). from aquilia.filesystem import list_dir # Returns list[str] of direct child names (files/folders) items = await list_dir("./modules") print(items) # ['core', 'users', 'auth'] Scanning Directory with Metadata (scan_dir) Retrieves list of DirEntry objects with cached status details. from aquilia.filesystem import scan_dir entries = await scan_dir("./data") for entry in entries: if entry.is_file_cached: print(f"File: at ") elif entry.is_dir_cached: print(f"Directory: ") Creating Directories (make_dir) Create a folder structure on the host disk safely. from aquilia.filesystem import make_dir # parents=False (raises if parent missing), exist_ok=False (raises if already exists) by default await make_dir("./uploads/images", parents=True, exist_ok=True) Removing Directories Delete empty directories or recursively prune folder trees. from aquilia.filesystem import remove_dir, remove_tree # 1. remove_dir - Deletes empty directory (raises if not empty) await remove_dir("./temp_folder") # 2. remove_tree - Deletes directory and all contents recursively # Silently ignore deletion exceptions if path does not exist await remove_tree("./cache_files", ignore_errors=True) Temporary Files & Directories Create self-cleaning files and folders using secure, context-managed wrappers. from aquilia.filesystem import async_tempfile, async_tempdir # 1. Temporary File Context async with async_tempfile(suffix=".csv", prefix="export-") as tmp: # tmp is an AsyncFile handle open in w+b mode await tmp.write(b"id,name\\n1,Alice") await tmp.flush() print(f"Temporary file created at: ") # File is closed and unlinked automatically here # 2. Temporary Directory Context async with async_tempdir() as tmpdir: # tmpdir is an AsyncPath object await (tmpdir / "manifest.json").write_text(' ') print(f"Temporary directory path: ") # Directory and all nested files deleted recursively on block exit File Locking Utilize cross-process advisory locks to coordinate access to files. from aquilia.filesystem import AsyncFileLock, read_file, write_file # Acquire exclusive write lock (blocks until acquired) async with AsyncFileLock("db.lock"): data = await read_file("db.json") # Mutate data await write_file("db.json", data) # Acquire lock with a timeout threshold (raises LockAcquisitionError on timeout) lock = AsyncFileLock("process.lock", timeout=5.0) try: async with lock: # Exclusive execution block pass except LockAcquisitionError: print("Could not acquire lock, proceeding to fallback") Chunk Streaming Stream files in binary chunks to avoid high RAM usage on large files: from aquilia.filesystem import stream_read, stream_copy # Stream read a file (yields bytes chunks) async for chunk in stream_read("archive.tar.gz", chunk_size=1024 * 64): process_chunk(chunk) # Stream copy directly from source to destination bytes_copied = await stream_copy("large.mp4", "backup.mp4", chunk_size=1024 * 1024) Path Globbing Search directory trees for files matching glob rules using the AsyncPath model: from aquilia.filesystem import AsyncPath root = AsyncPath("./src") # Find all python files recursively async for filepath in root.glob("**/*.py"): print(f"Found code: (Parent: )") )

### Code Examples
```python
from aquilia.filesystem import list_dir

# Returns list[str] of direct child names (files/folders)
items = await list_dir("./modules")
print(items)  # ['core', 'users', 'auth']
```

```python
from aquilia.filesystem import scan_dir

entries = await scan_dir("./data")
for entry in entries:
    if entry.is_file_cached:
        print(f"File: {entry.name} at {entry.path}")
    elif entry.is_dir_cached:
        print(f"Directory: {entry.name}")
```

```python
from aquilia.filesystem import make_dir

# parents=False (raises if parent missing), exist_ok=False (raises if already exists) by default
await make_dir("./uploads/images", parents=True, exist_ok=True)
```



---

## Providers Overview
**URL**: `https://tubox.cloud/docs/providers`

function DeploymentArchitecture() = useTheme() const isDark = theme === 'dark' return ( DIAGNOSTICS aq doctor & validate COMPILATION docker build amd64 REGISTRY PUSH docker push image RESOLUTION owner & config lookup PROVISIONING api deploy & vars sync LIVENESS POLL wait live or rollback ) } Providers Overview Cloud provider integrations, architecture, and deployment strategy Aquilia features a highly decoupled, container-first deployment pipeline. While the framework provides CLI commands to generate raw configuration files for Kubernetes, Nginx, Docker Compose, and Makefiles, it also offers first-class PaaS provider integrations, allowing developers to configure and deploy workspaces in a single command. Container-First Strategy Aquilia treats containerization as a fundamental building block, rather than an afterthought. Because the runtime is built around self-contained ASGI structures and manifest configurations, any Aquilia workspace can be packaged into an OCI-compliant container image. The framework leverages this by exposing a two-tiered deployment strategy: 1. Static Infrastructure-as-Code Generate local configs via commands like aq deploy dockerfile, aq deploy k8s, or aq deploy nginx. This allows complete portability to custom cloud clusters, VPS nodes, or in-house hardware. 2. Managed PaaS Integration Direct, API-driven deployments to managed platforms like Render. The framework introspects your active workspace features and maps them directly to cloud services, databases, cache layers, environment variables, and auto-scaling rules. Deployment Pipeline Architecture The orchestration path flows sequentially from the local workstation to the cloud provider. Here is how the pipeline connects local diagnostics, container building, registry synchronization, and API service provisioning: , , , , , , ].map((item, i) => ( ))} Configuration Approaches Aquilia supports two distinct ways to define Render integration settings in workspace.py: the Fluent API Integration and the Class-Based Configuration (Recommended). Method 1: Class-Based Config (Recommended) Defined inside the environment layering configurations inheriting from AquilaConfig. This is the recommended approach because it supports environment-specific overrides (e.g., using different machine plans or ports in dev vs. production environments) and supports twelve-factor variables via Env(). Method 2: Fluent API Integration Defined by instantiating a RenderIntegration object and passing it directly to the workspace's integrate() method. This is suitable for simpler, monolithic configurations that do not use multi-environment config layering. Next Chapters 01 Render PaaS Integration Deployment pipeline workflow details, API clients, and service configuration payloads. 02 Secure Credential Store Key derivation cryptography, encrypted credentials payload formatting, and local audit logs. 03 CLI Reference Guide Complete command flags, environment variable synchronizations, and CLI diagnostics. ) } function ArrowRightIcon() { return ( )

### Code Examples
```python
from aquilia import Workspace, AquilaConfig, Env, Secret

class BaseEnv(AquilaConfig):
    env = "dev"
    # General defaults here...

class ProdEnv(BaseEnv):
    env = "prod"

    class render(AquilaConfig.Render):
        service_name  = "my-prod-backend"
        region        = "frankfurt"              # Oregon is default
        plan          = "standard"               # Free, Starter, Standard, Pro...
        num_instances = 2
        image         = Env("RENDER_IMAGE", default="docker.io/myorg/myapp:latest")
        health_path   = "/_health"
        port          = 8000

workspace = (
    Workspace("my-production-app")
    .env_config(ProdEnv)
)
```

```python
from aquilia import Workspace, Module
from aquilia.integrations import RenderIntegration

workspace = (
    Workspace("my-production-app")
    .runtime(mode="prod", host="0.0.0.0", port=8000, workers=4)
    .integrate(
        RenderIntegration(
            service_name="my-prod-service",
            region="frankfurt",
            plan="standard",
            num_instances=2,
            image="docker.io/myorg/myapp:latest",
            health_path="/_health",
            auto_deploy="no",
        )
    )
)
```



---

## Render PaaS Deployments
**URL**: `https://tubox.cloud/docs/providers/render`

Render PaaS Deployments Full lifecycle deployment orchestration, client libraries, and payloads The Render integration facilitates zero-downtime, fully-configured deployments. When you execute a deployment, Aquilia compiles your code, packages it inside a production-ready Docker container, wires dependency-injected integrations, configures security headers, provisions Render services, and polls until the system is healthy. Deployment Prerequisites To orchestrate deployments to the Render cloud platform, you must establish two distinct trust endpoints beforehand: Render API Authentication: You must configure your Render API token locally. This can be accomplished either via the interactive aq provider login render command or via the Aquilia Admin Panel configuration settings. Docker Registry Authorization: Because Render does not host custom container images directly, it relies on pulling built images from an external registry (e.g., Docker Hub, GitHub Container Registry). You must run docker login on your workstation so the deployer can push the compiled image to your repository. Deployment Pipeline Workflow Deploying an application executes a structured multi-phase orchestration pipeline managed by RenderDeployer : 1 Pre-flight Diagnostics Runs aq doctor and aq validate. The system inspects your dependency injection graph for unresolved services, checks module manifests for routing conflicts, and verifies that the local configuration is valid. 2 Container Compilation If the workspace contains a Dockerfile (or if one is generated on the fly via aq deploy dockerfile), the deployer spawns a Docker build process to compile your local workspace into a target image with the linux/amd64 architecture. 3 Docker Registry Push Validates Docker registry login credentials. The deployer pushes the compiled image to the remote container registry (such as Docker Hub or GHCR), so that Render can pull the image during its deployment run. 4 Owner and Context Introspection Retrieves workspace owner info from Render's API. The deployer inspects your active workspace integrations. If the workspace has has_db, has_cache, or has_auth modules active, Aquilia automatically structures corresponding environment variables: DATABASE_URL for PostgreSQL integrations REDIS_URL for Redis integrations AQ_AUTH_SECRET (cryptographically generated crypt-secure value for token validations) AQ_SIGNING_SECRET (cryptographically generated signing seed) 5 Render Provisioning & Webhook Setup Creates the service in Render (or patches the existing configuration if already provisioned). Synchronizes environment variables and attaches persistent disks if specified. 6 HTTP Headers Injection Injects standard security headers to secure the service (e.g. Strict-Transport-Security, X-Content-Type-Options, and X-Frame-Options: DENY) directly into Render's ingress routers. 7 Autoscaling & Deployment Wait Applies scaling targets and triggers the deployment. The pipeline loops, polling the Render deployment endpoint until the service status goes live. In the event of a build or start failure, the deployer aborts and rolls back to the previous deployment ID. The Render API Client The RenderClient class is a synchronous Python client implementing the official Render API v1. To prevent dependency bloat and eliminate supply-chain vulnerabilities, the client is written using Python's standard library urllib.request. It incorporates transient failure retries, cursor-based pagination, and automatic rate-limit throttling (by respecting the API's Retry-After headers with exponential backoff). The Render Deployer The RenderDeployer orchestrates the deployment process. It takes the credentials token from the secure credential store, reads configuration from workspace.py, and coordinates the compilation, upload, and verification phases. Payload Architecture When creating or patching services, the RenderDeployConfig converts snake_case structures into camelCase JSON properties required by the Render REST endpoints: POST /v1/services (Service Creation) Next Chapters 02 Secure Credential Store Key derivation cryptography, encrypted credentials payload formatting, and local audit logs. 03 CLI Reference Guide Complete command flags, environment variable synchronizations, and CLI diagnostics. ) } function ArrowRightIcon() { return ( )

### Code Examples
```python
from aquilia.providers.render import RenderClient

# Instantiating client
client = RenderClient(token="rnd_xxxxxxxxxxxx")

# Querying services
services = client.list_services(limit=20)
for svc in services:
    print(f"Service: {svc.name} | Status: {svc.status} | Region: {svc.region}")

# Fetching deploy status
deploy_info = client.get_deploy(service_id="srv-abc123xyz", deploy_id="dep-12345")
print(f"Deploy State: {deploy_info.status}")
```

```python
from pathlib import Path
from aquilia.providers.render import RenderClient, RenderDeployer, RenderDeployConfig

# 1. Initialize API Client
client = RenderClient(token="rnd_xxxxxxxxxxxx")

# 2. Build deployment config contract
config = RenderDeployConfig(
    service_name="production-backend",
    image="docker.io/myorg/backend:v1.0.0",
    region="oregon",
    num_instances=2,
)

# 3. Create deployer and run
deployer = RenderDeployer(client, workspace_root=Path("/app"), config=config)
result = deployer.deploy()

if result.success:
    print(f"Successfully deployed! Live URL: {result.url}")
else:
    print(f"Deployment failed. Steps completed: {result.steps_completed}")
    print(f"Errors encountered: {result.errors}")
```

```python
{
  "name": "my-prod-service",
  "type": "web_service",
  "autoDeploy": "no",
  "image": {
    "imagePath": "docker.io/myorg/myapp:latest",
    "registryCredentialId": "rc-123456"
  },
  "serviceDetails": {
    "plan": "starter",
    "region": "oregon",
    "numInstances": 2,
    "healthCheckPath": "/_health",
    "envVars": [
      { "key": "AQUILIA_ENV", "value": "prod" },
      { "key": "AQ_SERVER_PORT", "value": "8000" }
    ]
  }
}
```



---

## Secure Credential Store
**URL**: `https://tubox.cloud/docs/providers/security`

Secure Credential Store Cryptographic protections, storage layout, and audit logging Local environment security is a cornerstone of the Aquilia deployment pipeline. To prevent API tokens from being stored in plain text, committed to version control, or leaked in history files, the framework incorporates a multi-layered cryptographic store called RenderCredentialStore . Cryptographic Protection Model The credential store implements a defense-in-depth model, securing Render tokens (stored in the credentials.surp binary file) through a series of cryptographic boundaries: 1. Machine-Bound Key Derivation Keys are never saved on disk. Instead, the encryption key is derived dynamically using PBKDF2-HMAC-SHA512 configured with 600,000 iterations. The derivation payload incorporates machine-specific identifiers: host hostname, current user name, hardware platform architecture, and python major/minor version. This prevents credentials from being copied and decrypted on another machine. 2. Authenticated Encryption (AES-256-GCM) The token is encrypted with AES-256-GCM using a unique 96-bit random nonce generated for each write operation. This provides authenticated confidentiality, ensuring that any external manipulation of the ciphertext results in decryption failure. 3. Tamper-Proof Plaintext Canary An encrypted plaintext canary ("AQUILIA_CANARY_OK") is embedded in the binary payload. During the loading process, the canary is decrypted first. If key derivation parameters are incorrect (such as moving the file to another PC), the canary check fails immediately, avoiding partial decrypt errors. 4. In-Memory Security & Zeroing To prevent security leaks via core dumps or system memory scraping, the credential store uses Python's ctypes module to overwrite mutable buffers with zeros (ctypes.memset) immediately after use, ensuring sensitive data is purged from memory. On-Disk Storage Layout Credential items are isolated under the local project workspace configuration folder. The directory is located at: <workspace_root>/.aquilia/providers/render/ Binary Envelope Format The credentials.surp file follows a structured binary layout, verified strictly on read: Byte Offset Field Name Size Description 0 - 3 Magic Bytes 4 bytes Standard header signature "AQCR" 4 Version 1 byte Envelope version (currently 2) 5 Cipher ID 1 byte Cipher suite choice (e.g. 1 = AES-GCM) 6 - 13 Timestamp 8 bytes Double float indicating write time (big-endian) 14 - 17 TTL Seconds 4 bytes Expiration limit (0 indicates no expiration) 18 - 49 Salt 32 bytes Cryptographic salt for key derivation 50 - 61 Nonce 12 bytes Random GCM initialization vector 62 - 65 Token Len 4 bytes Size (uint32) of the encrypted payload 66 ... Ciphertext N bytes AES-256-GCM encrypted token ... + 16 GCM Auth Tag 16 bytes GCM integrity authentication tag ... + 64 HMAC 64 bytes HMAC-SHA512 checksum covering all fields Audit Logging Every interaction with the credential store (such as executing aq provider status or deploying via aq deploy render) writes an entry to audit.log. This creates a secure history trail, letting developers audit authentication actions on a local workstation. Next Chapters 03 CLI Reference Guide Complete command flags, environment variable synchronizations, and CLI diagnostics. 01 Providers Overview Deployment strategy, container building pipelines, and configuration approaches. ) } function ArrowRightIcon() { return ( )

### Code Examples
```python
.aquilia/
└── providers/
    └── render/
        ├── credentials.surp   # Encrypted token & signing signatures (0o600 permissions)
        ├── config.json         # Non-sensitive workspace metadata (owner name, default region)
        └── audit.log           # File log tracking read, write, and verify events
```

```python
- timestamp: "2026-07-12T16:04:12Z"
  event: "save"
  owner: "Production Workspace"
  region: "oregon"
  metadata: { email: "admin@mycorp.com" }
  status: "success"

- timestamp: "2026-07-12T16:15:33Z"
  event: "load"
  caller: "aq deploy render"
  status: "success"
```



---

## CLI Command Reference
**URL**: `https://tubox.cloud/docs/providers/cli`

CLI Command Reference Detailed documentation for aq provider and aq deploy CLI commands The aq command-line tool provides interactive terminal flows for managing cloud logins, updating remote service variables, and deploying projects. All commands leverage structured terminal output, featuring status indicators, execution phases, and diagnostic warnings. Provider Authentication Commands Authentication is the gatekeeper for all provider integrations. Use the following commands to check, establish, or purge workspace credentials: aq provider login render Authenticates with the Render API using a personal API bearer key. The key is validated by listing account owners and is then encrypted via RenderCredentialStore . Argument: PROVIDER_NAME (must be render) Options: --token, -t: API bearer token. If omitted, prompts securely. If -, reads from standard input. --region, -r: Default deployment region (e.g. frankfurt, oregon). Default is oregon. aq provider status render Checks the state of your local credentials, runs decryption tests, queries connection speed to Render, and displays owner email metadata. aq provider logout render Erases stored credentials. To prevent recovery of secret key remnants on SSD controllers, the command overwrites the local credentials.surp file with random bytes before deletion. Render Operational Commands The aq provider render subcommands allow direct management of Render services, deployments, and logs: 1. aq provider render services Lists all services provisioned inside the active Render workspace owner account. Displays name, region, status, and type. 2. aq provider render deploys Lists deployment histories for a target service. Required Option: --service, -s SERVICE_NAME 3. aq provider render deploy-trigger Triggers a new manual deployment for the target service on Render. Required Option: --service, -s SERVICE_NAME 4. aq provider render deploy-cancel Cancels an active, ongoing build or deployment on Render. Required Argument: DEPLOY_ID (e.g. dep-xxxx) Required Option: --service, -s SERVICE_NAME 5. aq provider render deploy-rollback Rolls back a service to a previous deployment. Triggered automatically on failure during aq deploy render runs. Required Argument: DEPLOY_ID Required Option: --service, -s SERVICE_NAME 6. aq provider render logs Retrieves recent application logs. Output is formatted with color-coded severity levels (INFO, WARN, ERROR). Required Option: --service, -s SERVICE_NAME Options: --limit, -l: Number of log lines to show (default: 50). --level: Filter severity: info | warn | error. Environment Variable Management Use the aq provider render env subcommand group to synchronize container environment variables: List Variables Set/Update Variable Delete Variable Deployment Commands Once authenticated, run aq deploy render to trigger the deployment run. The CLI supports multiple options to customize and query services directly: 1. aq deploy render (Standard Deployment) Compiles, validates, builds, pushes, and provisions the workspace. It prints progress updates for each step. Options: --image, -i: Docker image path (e.g. docker.io/user/repo:tag). --region, -r: Deployment datacenter (oregon | frankfurt | ohio | virginia | singapore). --plan: Compute tier size (free | starter | standard | pro | pro_plus). --num-instances: Explicit container scaling factor. --service-name: Custom service name override on Render. --registry-credential-id: Private registry credential ID (if pulling from a private registry). --force, -f: Overwrite configuration without prompt checks. 2. aq deploy render --dry-run (Dry Run Planning) Synthesizes the configuration properties, compiles the local OCI configuration, resolves dependency mappings, and prints the target payload structure without writing any files or contacting Render endpoints. 3. aq deploy render --status (Query Live Status) Connects to the Render API and prints the active status (e.g. creating, live, or suspended), public URL, deployment history logs, and healthy instance count. 4. aq deploy render --destroy (Teardown Service) Tears down and destroys the deployed Render web service and associated configuration. To prevent accidental production data loss, this command requires interactive confirmation unless --yes is supplied. Next Chapters 01 Providers Overview Deployment strategy, container building pipelines, and configuration approaches. 02 Render PaaS Integration Deployment pipeline workflow details, API clients, and service configuration payloads. ) } function ArrowRightIcon() { return ( )

### Code Examples
```python
# Run interactively (will prompt for token securely)
aq provider login render

# Run with inline arguments
aq provider login render --token rnd_xxxxxx --region frankfurt

# Pipe token from a secrets environment variable
echo $RENDER_TOKEN | aq provider login render --token -
```

```python
aq provider status render
```

```python
aq provider logout render
```



---

## Release 1.3.2
**URL**: `https://tubox.cloud/releases/1.3.2`

Aquilia v1.3.2 Release Notes — "Specula API Observatory" Aquilia v1.3.2 introduces **Specula**, a major evolution of the framework's documentation and API exploration subsystem. Specula completely replaces the legacy OpenAPI 3.1.0 generator and static Swagger/ReDoc pages with a compiled, introspective ASGI dashboard (the Specula Observatory), reactive hot-reloading streams, automated security and clearance level mapping, a schema-synthesized mock server, and Postman/Insomnia collection exporters. Table of Contents 1. [Specula Observatory UI & Integration](observatory.md) * The new dashboard philosophy. * Integrating Specula via `Integration.specula(...)`. * UI branding and Server-Sent Events (SSE) live streams. 2. [Spec Compilation & Schema Inference](compilation.md) * The compiler-integrated `SpeculaBuilder`. * Python-to-JSON Schema type mapping. * Multi-strategy request body and response resolution. 3. [Automated Security & Clearance Detection](security.md) * Inferred security schemes from pipeline guards. * Integrated authorization clearance level detection. * Extended metadata (`x-specula-security`) vendor extensions. 4. [Mock Server & Collection Exports](mock_exports.md) * Interactive mocking engine at `/specula/mock`. * Schema synthesis with configurable recursion depth limits. * Dynamic exports for Postman v2.1 and Insomnia v4. 5. [Migration Guide](migration.md) * Removing legacy `OpenAPIIntegration` references. * Replaced classes, paths, and deprecations. --- Key Subsystem Improvements 1. **Compilation over Code Scanning**: No more parsing source files or class matching at runtime. Specula extracts endpoint specs directly from Aquilia's compiled in-memory ASGI routing topology. 2. **Developer Reactivity**: Hot-reloading modules push Specula spec invalidations down active Server-Sent Events (SSE) connections, immediately refreshing the developer's dashboard. 3. **Simulated Sandbox**: Frontends can start testing integration before the backend endpoints are written. The mock server synthesizes response payloads matching the exact JSON schemas defined in Contracts or ORM Models. 4. **Complete Security Transparency**: Exposes exact pipeline guards, role requirements, and AccessLevel clearance levels to ensure complete architectural observability.


---

## Release 1.3.2: Compilation
**URL**: `https://tubox.cloud/releases/1.3.2/compilation`

Spec Compilation & Schema Inference Specula features a compiler-integrated OpenAPI 3.1.0 specification engine (`SpeculaBuilder`). Instead of scanning source files at startup, it introspects Aquilia's compiled routing topology in memory, extracting schemas, bindings, parameters, and outputs. --- Python-to-JSON Schema Mapping When generating schema objects, Specula inspects standard type hints and maps them to their OpenAPI 3.1.0 JSON Schema equivalents. Specula is fully compliant with the OpenAPI 3.1.0 specification: * **Option types** use `oneOf` blocks combined with `{"type": "null"}` instead of the deprecated `nullable` property. * **Complex Python structures** map cleanly to nested schemas. Mapping Reference Table | Python Type Hint | JSON Schema Equivalent | | :--- | :--- | | `str` | `{"type": "string"}` | | `int` | `{"type": "integer"}` | | `float` | `{"type": "number", "format": "double"}` | | `bool` | `{"type": "boolean"}` | | `bytes` | `{"type": "string", "format": "binary"}` | | `None` / `type(None)` | `{"type": "null"}` | | `Optional[T]` / `T \| None` | `{"oneOf": [{"type": T_schema}, {"type": "null"}]}` | | `list[T]` / `List[T]` | `{"type": "array", "items": T_schema}` | | `dict[str, T]` / `Dict[str, T]` | `{"type": "object", "additionalProperties": T_schema}` | | `tuple[T1, T2]` | `{"type": "array", "prefixItems": [T1_schema, T2_schema], "minItems": 2, "maxItems": 2}` | | `Contract` / `Model` | `{"$ref": "#/components/schemas/Name"}` | --- Request Body Inference Strategies Specula resolves request payloads through a 5-tier inference engine, prioritizing explicit developer configurations over implicit code analysis. 1. The `request_contract` Parameter If a route decorator declares a validation contract directly, the builder generates a reference schema: 2. Contract Parameter Type Hints If a route handler receives a parameter type-hinted with an Aquilia `Contract` class, it is automatically mapped as the JSON body payload: 3. Explicit `Body` Metadata Annotations If a parameter is annotated using standard Python type annotations with `Body()`, it is mapped to a properties-based object payload: 4. Docstring Body Mappings The builder parses Google-style docstrings, extracting raw examples from `Body:` headers: 5. Source Code Introspection As a fallback, Specula scans the compiled handler source code for extraction patterns: * Finding `await ctx.json()` infers a generic `application/json` object. * Finding `await ctx.form()` infers an `application/x-www-form-urlencoded` form. --- Response Shapes Resolution Specula automatically maps success and error response channels. Success Shapes 1. **Model / Contract Mappings**: Declaring `response_model` or `response_contract` registers the corresponding schema (input contracts map with `Input` suffix, output contracts map directly) and binds them under status code `2xx`. 2. **Standard Output Fallbacks**: If no return contract is specified, Specula inspects handler code: * Calls to `Response.json(...)` default to `application/json`. * Calls to `Response.html(...)` or template rendering functions default to `text/html`. * References to `SSEResponse(...)` default to `text/event-stream`. Error Shapes * **Raises Docstring Section**: Specula compiles exception details declared in Google-style docstrings into typed status responses: Specula compiles this raises annotation into a structured `404 Not Found` response returning the standard `AquiliaError` schema. * **Auto-Validation Errors**: All write routes (`POST`, `PUT`, `PATCH`) automatically carry a default `422 Unprocessable Entity` response mapping returning the structured `AquiliaValidationError` schema.

### Code Examples
```python
@POST("/users", request_contract=UserCreateContract)
async def create_user(self, ctx: RequestCtx): ...

```

```python
@POST("/users")
async def create_user(self, ctx: RequestCtx, payload: UserCreateContract): ...

```

```python
@POST("/items")
async def create_item(self, ctx: RequestCtx, amount: Annotated[int, Body()] = 1): ...

```



---

## Release 1.3.2: Migration
**URL**: `https://tubox.cloud/releases/1.3.2/migration`

OpenAPI to Specula Migration Guide Aquilia v1.3.2 deprecates and removes the old static OpenAPI/Swagger engine. This guide outlines how to migrate your configuration, imports, and endpoints. --- 1. Configuration & Integration Upgrades The old `OpenAPIIntegration` has been replaced by `SpeculaIntegration`. In your `workspace.py`, update your registrations: Legacy Style (Removed) New Style (Active) Parameter Mapping Table Use this reference table to map configuration options from legacy OpenAPI attributes to Specula attributes: | Legacy OpenAPI Option | New Specula Option | Notes | | :--- | :--- | :--- | | `docs_path` | `ui_path` | Default changes from `/docs` to `/specula`. | | `openapi_json_path` | `json_path` | Default changes from `/openapi.json` to `/specula/spec.json`. | | `redoc_path` | (Removed) | ReDoc is deprecated. Use the unified Specula dashboard. | | `swagger_ui_theme` | `ui_theme` | Values: `"auto"`, `"light"`, `"dark"`. | | `swagger_ui_config` | (Removed) | Replaced by direct dashboard configuration. | --- 2. Replaced Imports & Engines If you manually generated specs, update your imports and instantiation: --- 3. Redirects & Endpoint Updates The automatic redirects mapping legacy paths are no longer registered. Update links: * **Swagger UI Docs**: Old path `/docs` is replaced by `/specula`. * **ReDoc Docs**: Old path `/redoc` is deprecated. Use the unified `/specula` dashboard. * **JSON Specification**: Old path `/openapi.json` is replaced by `/specula/spec.json`. * **YAML Specification**: Specula now supports rendering YAML natively at `/specula/spec.yaml`.

### Code Examples
```python
# Replaced by Specula
workspace.integrate(Integration.openapi(
    title="Store API",
    docs_path="/apidocs",
    swagger_ui_theme="dark"
))

```

```python
from aquilia.integrations import SpeculaIntegration

# Option A: Direct class registration
workspace.integrate(SpeculaIntegration(
    title="Store API",
    ui_path="/apidocs",
    ui_theme="dark"
))

# Option B: Fluent helper
# workspace.integrate(Integration.specula(
#     title="Store API",
#     ui_path="/apidocs",
#     ui_theme="dark"
# ))

```

```python
# --- Legacy Imports (Removed) ---
# from aquilia.controller.openapi import OpenAPIConfig, OpenAPIGenerator
# config = OpenAPIConfig(title="API")
# spec = OpenAPIGenerator(config=config).generate(router)

# --- New Imports (Active) ---
from aquilia.specula.config import SpeculaConfig
from aquilia.specula.schema.builder import SpeculaBuilder

config = SpeculaConfig(title="API")
spec = SpeculaBuilder(config=config).build(router)

```



---

## Release 1.3.2: Mock_Exports
**URL**: `https://tubox.cloud/releases/1.3.2/mock_exports`

Mock Server & Collection Exports Specula features a schema-driven Mock Server and dynamic collection exporters to support rapid frontend integration and testing. --- Interactive Mock Server (`/specula/mock`) The mock server lets developers call any documented API endpoint and receive a plausible response payload without executing any business logic. Enabling the Mock Server The mock server is disabled by default. Enable it in your workspace configuration: How Payload Synthesis Works When a request is sent to `/specula/mock/<path>`, the mock router matches the path against the compiled API specification. It resolves the success response (`200`, `201`, or `202`) and inspects the JSON Schema: 1. **Explicit Examples**: If the schema or individual fields define an `example` or `examples` block, those values are returned directly. 2. **Plausible Synthesis**: If no examples are configured, Specula inspects the schema field types and synthesizes logical placeholders: * **Formatting Matchers**: String formats like `email`, `uuid`, `uri`, and `date-time` map to real formatted values (e.g. `user@example.com`, `550e8400-e29b-41d4-a716-446655440000`). * **Key Name Inference**: If a string field matches common keys (such as `email` or `url`), appropriate values are auto-injected. * **Standard Defaults**: Integers default to `42`, numbers to `3.14`, booleans to `True`, and arrays to single-item arrays. 3. **Recursion Safety**: Self-referencing models (e.g., a node containing a list of children of its own type) are automatically truncated when nesting depth exceeds `mock_max_depth` (default `4`). --- Exporters Specula exposes dynamic endpoints to download client collections configured with your current workspace routing topology and security schemes. 1. Postman Collection v2.1 * **Endpoint**: `/specula/export/postman` * **Output**: A compliant Postman v2.1 collection JSON file. * **Details**: * Groups endpoints into folders based on their tags or manifest module names. * Translates route variables like `/users/<id:int>` into Postman-compatible environment syntax: `/users/{{id}}`. * Pre-populates request bodies with JSON examples synthesized from Contract definitions. * Embeds default authorization headers mapped to the `{{access_token}}` environment variable. 2. Insomnia v4 Collection * **Endpoint**: `/specula/export/insomnia` * **Output**: A standard Insomnia v4 export file. * **Details**: * Includes workspace configuration mapping the current API. * Sets up base environment variables referencing `{{ _.base_url }}`. * Configures HTTP methods, headers, and body payloads automatically.

### Code Examples
```python
workspace.integrate(Integration.specula(
    title="Customer API",
    mock_server_enabled=True,
    mock_max_depth=4 # limit recursive definitions mapping
))

```



---

## Release 1.3.2: Observatory
**URL**: `https://tubox.cloud/releases/1.3.2/observatory`

Specula Observatory UI & Integration The Specula Observatory is a built-in interactive dashboard served natively by Aquilia at `/specula`. It provides a CDN-free developer sandbox that works entirely offline, inline-cached, and features hot-reload awareness. Workspace Integration Specula is registered at the workspace level inside `workspace.py`. You configure it using the `Integration.specula(...)` builder method or by importing and instantiating `SpeculaIntegration` directly: --- Configuration Reference (`SpeculaConfig`) When you configure Specula, your parameters map to the `SpeculaConfig` dataclass. The primary settings available are: | Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | **Info / Branding** | | | | | `title` | `str` | `"Aquilia API"` | Name of the API, visible in the UI header and spec exports. | | `version` | `str` | `"1.0.0"` | The current API release version. | | `description` | `str` | `""` | Detailed description of the API. | | `ui_theme` | `str` | `"auto"` | `"auto"` (matches system preferences), `"light"`, or `"dark"`. | | `ui_primary_color`| `str` | `"#22c55e"` | Hex code for branding the main interface buttons and tags. | | **URL Paths** | | | | | `ui_path` | `str` | `"/specula"` | Browser path to view the Observatory HTML dashboard. | | `json_path` | `str` | `"/specula/spec.json"`| JSON endpoint serving the raw OpenAPI 3.1.0 spec. | | `yaml_path` | `str` | `"/specula/spec.yaml"`| YAML endpoint serving the raw OpenAPI 3.1.0 spec. | | `stream_path` | `str` | `"/specula/stream"`| SSE stream pushing route updates to the UI. | | `mock_path` | `str` | `"/specula/mock"` | Endpoint path for the mock server router. | | **Feature Toggles** | | | | | `enabled` | `bool` | `True` | Master toggle to enable or disable Specula routes. | | `include_internal`| `bool` | `False` | Whether routes matching `/_*` are included in the spec. | | `detect_security` | `bool` | `True` | Scan route guards and decorators to construct security schemes. | | `mock_server_enabled`| `bool` | `False` | Set `True` to enable schema-synthesized mock responses. | | `spec_cache_ttl` | `int` | `60` | In-memory cache duration (in seconds) for compiled spec payloads. | --- Hot-Reloading SSE Stream (`/specula/stream`) During development, Aquilia runs with file watchers. When you modify controller code, the worker process reloads. Specula exposes a native ASGI Server-Sent Events (SSE) stream endpoint at `/specula/stream`. When the dashboard is loaded in a browser, it subscribes to this stream. When a reload happens, the server pushes an invalidation event down the pipe: The Observatory frontend listens to this event and immediately fetches the newly compiled specification and routes dynamically, refreshing the client view with zero hard refreshes. --- Production Security Locks By default, the Specula Observatory is fully open. In production environments, you can lock access down to authenticated users with specific roles: When `docs_auth_required` is enabled, the Specula controller inspects the request context using the configured `AuthMiddleware` pipeline. If the visitor lacks the required roles, they receive a `403 Forbidden` response.

### Code Examples
```python
# workspace.py
from aquilia.workspace import Workspace
from aquilia.integrations import Integration, SpeculaIntegration

workspace = (
    Workspace("user-portal")
    
    # Style A: Fluent Integration helper
    .integrate(Integration.specula(
        title="User Portal API",
        version="1.4.0",
        ui_theme="dark"
    ))
    
    # Style B: Direct Instantiation (provides static checks and autocomplete)
    # .integrate(SpeculaIntegration(
    #     title="User Portal API",
    #     version="1.4.0",
    #     ui_theme="dark"
    # ))
)

```

```python
{"event": "update", "data": {"status": "invalidated", "version": "2.0.0"}}

```

```python
workspace.integrate(Integration.specula(
    title="Corporate Core API",
    docs_auth_required=True,
    docs_roles=["admin", "ops-team"]
))

```



---

## Release 1.3.2: Security
**URL**: `https://tubox.cloud/releases/1.3.2/security`

Automated Security & Clearance Detection Specula integrates with Aquilia's security pipeline to automatically detect, map, and document authentication configurations. It translates pipeline guards and clearance levels into standard OpenAPI security requirements and rich custom metadata tags. --- Inferred Security Schemes The spec builder scans your controllers' and routes' pipeline nodes and handler decorators to identify authentication mechanisms. It automatically registers and configures security definitions in the OpenAPI `components.securitySchemes` catalog: | Inferred Guard Class Name | Generated Security Scheme | Schema Details | | :--- | :--- | :--- | | `AuthGuard` / `Auth` / `@authenticated` | `bearerAuth` | HTTP Bearer token (JWT) authentication. | | `ApiKeyGuard` / `ApiKey` | `apiKeyAuth` | `X-API-Key` request header authorization. | | `SessionGuard` / `Session` | `cookieAuth` | Session-based cookie verification (`session`). | | `BasicAuthGuard` / `Basic` | `basicAuth` | HTTP Basic authentication. | | `OAuth2Guard` / `OAuth2` | `oauth2` | OAuth2 Authorization Code flow. | --- Integrated Clearance Detection Specula integrates directly with the `aquilia.auth.clearance` system to identify role-based and attribute-based clearance levels. The builder resolves the merged clearance level from the controller boundary and individual route overrides: 1. **Public Routes**: If the effective clearance resolves to `AccessLevel.PUBLIC` (e.g. via `@grant(level=AccessLevel.PUBLIC)`), security requirements are omitted for that route. 2. **Protected Routes**: If the effective clearance is higher than public, `bearerAuth` is automatically registered as a requirement. --- Rich Metadata Extensions (`x-specula-security`) To support advanced observability and client generation, Specula embeds the full resolved authorization metadata in a custom vendor extension block (`x-specula-security`) inside each route's spec operation: This vendor block exposes: * **`authenticated`**: Boolean flag indicating if verification is required. * **`guards`**: Detailed list of active pipeline guard configurations, including roles, scopes, optional tags, resources, and evaluation settings. * **`clearance`**: The full clearance metadata, including `level` name, `level_value` integer, required `entitlements` lists, active `conditions` names, and matching resource `compartment` boundaries.

### Code Examples
```python
# Specula automatically registers bearerAuth with ["read", "write"] scopes
class OrderController(Controller):
    pipeline = [AuthGuard(), ScopeGuard("read", "write")]
    
    @GET("/")
    async def list_orders(self, ctx: RequestCtx): ...

```

```python
"x-specula-security": {
  "authenticated": true,
  "guards": [
    {
      "name": "RoleGuard",
      "type": "instance",
      "roles": ["admin", "compliance"],
      "require_all": false
    }
  ],
  "clearance": {
    "level": "INTERNAL",
    "level_value": 30,
    "entitlements": ["view_audit_logs", "override_fees"],
    "conditions": ["IsDuringOfficeHours", "IPRangeCondition"],
    "compartment": "finance"
  }
}

```



---

## Release 1.3.1
**URL**: `https://tubox.cloud/releases/1.3.1`

Aquilia v1.3.1 Release Notes — "Backend Refactoring" Aquilia v1.3.1 introduces a major rewrite of the authentication (`aquilia.auth`) and authorization subsystems. It moves away from rigid string-based strategies and hardcoded guard adapters in favor of a pluggable, class-based backend architecture, a unified permission engine, hardened session serialization, and token clock-skew tolerance. Table of Contents 1. [Pluggable Authentication Backends](backends.md) * The new `AuthBackend` protocol. * Built-in backends: `TokenBackend`, `SessionBackend`, `PasswordBackend`, `ApiKeyBackend`. * The `resolve_backend` helper and loading configuration. 2. [Unified Permission & Authorization Engine](guards.md#permissionengine) * Role DAG (Directed Acyclic Graph) inheritance. * Policy callables and scope checks. * Pluggable Flow Guards: `AuthGuard`, `RoleGuard`, `ScopeGuard`, `PolicyGuard`. * Context-First Decorators: `@authenticated`, `@roles_required`, `@scopes_required`, `@optional_auth`. 3. [Session Security Hardening](sessions.md) * Elimination of stale permission state in session cookies. * The lightweight `AuthPrincipal` serialization format. * Dynamic resolution of roles and scopes on every request. 4. [Migration Guide](migration.md) * Upgrading configuration settings from `strategies` to `backends`. * Replaced classes, decorators, and middleware. --- Key Refactoring Goals 1. **Pluggability**: Unify all authentication strategies (Bearer JWTs, Session cookies, Username/Password, API keys) under a single, reusable backend protocol. 2. **Dynamic Privileges**: Resolve permissions, roles, and scopes fresh from the database or cache on every request, preventing privilege escalation through stale session states. 3. **API Simplification**: Consolidate five parallel authorization subsystems (RBAC, ABAC, Clearance, Policy DSL, and custom adapters) into a single, cohesive `PermissionEngine`. 4. **Resiliency**: Handle clock drift in distributed clusters by introducing native clock-skew tolerance. 5. **DI Scope Performance**: Deprecate the class/object-based `ServiceScope` Enum in favor of high-performance raw string literals backed by `typing.Literal` to eliminate import-time namespace scanning and runtime attribute lookup overhead.


---

## Release 1.3.1: Backends
**URL**: `https://tubox.cloud/releases/1.3.1/backends`

Pluggable Authentication Backends In Aquilia v1.3.1, the authentication workflow is decomposed into single-responsibility **Backends**. A backend is a class that conforms to the `AuthBackend` protocol. It is responsible for accepting a credential dictionary and resolving it to an `Identity`. The `AuthBackend` Protocol The `AuthBackend` protocol is defined in `aquilia.auth.backends.base` using Python's structural subtyping (`typing.Protocol`): --- Built-in Backends Aquilia provides four native backends to cover standard flows: 1. `TokenBackend` Validates JWT Bearer tokens. It verifies signatures, checks `exp` and `nbf` claims (with clock-skew tolerance), and validates token revocation via `TokenManager`. * **Accepted Credentials**: `{"token": str}` * **Constructor**: 2. `SessionBackend` Restores identity from a cookie-backed session. It looks up the `identity_id` from the session data or from `session.principal`, and fetches the corresponding active identity. * **Accepted Credentials**: `{"session": Session}` * **Constructor**: 3. `PasswordBackend` Authenticates user login credentials. It checks for IP/username brute-force lockouts, resolves usernames or email addresses to an identity, compares password hashes, handles password re-hashing when algorithm parameters upgrade, and checks for multi-factor authentication (MFA) requirements. * **Accepted Credentials**: `{"username": str, "password": str}` * **Constructor**: 4. `ApiKeyBackend` Authenticates API requests via an opaque API key. It hashes the incoming key using `HMAC-SHA256` for lookup, checks expiration and revocation status, and verifies that the key carries the required scopes if requested. * **Accepted Credentials**: `{"api_key": str, "required_scopes": list[str] | None}` * **Constructor**: --- The Backend Resolver To simplify instantiation, the `resolve_backend` function maps string identifiers, class references, or dotted import paths to their instantiated backends: It maps: * Short names: `"token"` (TokenBackend), `"session"` (SessionBackend), `"password"` (PasswordBackend), `"api_key"` (ApiKeyBackend). * Class references: `TokenBackend`, `SessionBackend`, `PasswordBackend`, `ApiKeyBackend`. * Dotted paths: `"my_app.auth.backends.CustomBackend"`. Example Configuration in `workspace.py`

### Code Examples
```python
from typing import Any, Protocol, runtime_checkable
from aquilia.auth.core import Identity

@runtime_checkable
class AuthBackend(Protocol):
    def accepts(self, credentials: dict[str, Any]) -> bool:
        """Return True if the backend supports the provided credentials."""
        ...

    async def authenticate(self, credentials: dict[str, Any]) -> Identity | None:
        """Verify credentials and resolve them to an Identity.
        
        May raise specific auth faults (e.g., AUTH_TOKEN_EXPIRED, AUTH_INVALID_CREDENTIALS).
        """
        ...

```

```python
def __init__(self, token_manager: TokenManager, identity_store: IdentityStore)
  
```

```python
def __init__(self, identity_store: IdentityStore)
  
```



---

## Release 1.3.1: Guards
**URL**: `https://tubox.cloud/releases/1.3.1/guards`

Unified Authorization, Middleware & Decorators Aquilia v1.3.1 unifies identity resolution and request-scoped checks into a single middleware and permission engine. --- 1. Unified `PermissionEngine` The `PermissionEngine` (defined in `aquilia.auth.permissions`) is the central engine for evaluating roles, scopes, and policies. It replaces five separate historical systems and runs check assertions that raise appropriate exceptions on denial. Core API Methods * `define_role(role: str, *, permissions: list[str] | None = None, inherits: list[str] | None = None) -> None`: Declare a role and its transitively implied parents. * `role_implies(role: str, target: str) -> bool`: Query the role DAG structure. * `register_policy(key: str, policy: PolicyCallable) -> None`: Define a rule matching the signature `(identity, resource) -> bool`. * `check_role(identity: Identity, role: str) -> None`: Asserts role ownership; raises `AUTHZ_INSUFFICIENT_ROLE` on failure. * `check_scope(identity: Identity, scope: str) -> None`: Asserts scope ownership; raises `AUTHZ_INSUFFICIENT_SCOPE` on failure. * `check_policy(key: str, identity: Identity, resource: Any = None) -> None`: Asserts policy assertion passes; raises `AUTHZ_POLICY_DENIED` on failure. * `has_role(identity: Identity, role: str) -> bool`: Returns a boolean indicating role membership. * `has_scope(identity: Identity, scope: str) -> bool`: Returns a boolean indicating scope membership. * `evaluate_policy(key: str, identity: Identity, resource: Any = None) -> bool`: Returns a boolean indicating policy result. --- 2. Pluggable Flow Guards Guards (defined in `aquilia.auth.guards`) evaluate context and raise exceptions on denial. They can be placed directly in request pipelines or used as raw classes (for zero-configuration defaults). `AuthGuard` Verifies authentication status. * **Optional Mode**: When `optional=True`, anonymous users are allowed. * **Proactive Auth**: If the identity is not yet resolved, `AuthGuard` attempts to proactively extract and authenticate a Bearer token using DI container-resolved `AuthManager`. * **Signature**: `AuthGuard(auth_manager=None, optional=False)` `RoleGuard` Ensures the identity holds required roles. * **Resolution**: Uses `PermissionEngine` if found in the DI container; otherwise, falls back to direct membership testing of `identity.get_attribute("roles", [])`. * **Signature**: `RoleGuard(*roles, engine=None, require_all=True)` `ScopeGuard` Ensures the identity holds required scopes. * **Wildcards**: Supports the wildcard `"*"` scope. * **Signature**: `ScopeGuard(*scopes, require_all=True)` `PolicyGuard` Evaluates a policy registered in the permission engine. * **Signature**: `PolicyGuard(key, engine, resource=None)` --- 3. Context-First Decorators Decorators (defined in `aquilia.auth.decorators`) wrap handlers to execute guard checks and **inject parameters** into the handler's signature (e.g., `identity`, `user`, `session`, `principal`). `@authenticated` Requires an authenticated identity. * **Browser Redirection**: If a request is anonymous, has `redirect_if_html=True` or `login_url` configured, and accepts HTML, it performs a `303 Redirect` to the login page with a `next` query parameter. * **Signature**: `@roles_required` / `@scopes_required` Evaluates role or scope conditions before executing the controller action. `@optional_auth` Evaluates the proactive `AuthGuard(optional=True)` check. It injects the user if found but does not block anonymous traffic. `@requires` Composes multiple guards (both classes and instances) sequentially: --- 4. Unified `AuthMiddleware` The new unified `AuthMiddleware` (defined in `aquilia.auth.middleware`) coordinates credential resolution from backends on every incoming request. * **Signatures & Parameters**: * **Execution Flow**: 1. **Phase 1: Session Resolution**: If `session_engine` is provided, resolves the session and binds it to `ctx.session` and `request.state["session"]`. 2. **Phase 2: Credentials Extraction**: Extracts Bearer token, ApiKey, or Session from the request. 3. **Phase 3: Backend Authentication**: Loops through pluggable `backends` (defaults to `TokenBackend` and `SessionBackend`). The first backend that accepts the credentials and returns an `Identity` completes the phase. 4. **Phase 4: Requirement Enforcement**: If `require_auth=True` and no identity is resolved, returns a `401 Unauthorized` response immediately. 5. **Phase 5: Propagation**: Propagates the resolved identity to `request.state["identity"]`, `request.state["authenticated"]`, and `ctx.identity`. 6. **Phase 6: Downstream Execution**: Calls the next handler in the ASGI middleware chain. 7. **Phase 7: Session Commitment**: Commits session modifications back to the storage adapter.

### Code Examples
```python
def authenticated(
      func=None,
      *,
      login_url: str | None = None,
      redirect_if_html: bool = False,
      include_next: bool = True,
      next_param: str = "next",
      redirect_status: int = 303,
  )
  
```

```python
@roles_required("admin", "editor", require_all=False)
async def delete_post(self, ctx: RequestCtx) -> Response:
    ...

```

```python
@requires(AuthGuard, RoleGuard("admin"))
async def admin_only_action(self, ctx: RequestCtx) -> Response:
    ...

```



---

## Release 1.3.1: Migration
**URL**: `https://tubox.cloud/releases/1.3.1/migration`

Migration Guide: v1.3.0 to v1.3.1 Aquilia v1.3.1 consolidates and standardizes authentication and authorization. Follow this guide to upgrade your project. --- 1. Upgrading Configuration The string-based `strategies` setting has been removed. You must now configure the list of identity-resolution backends using the `backends` parameter. Additionally, the rate-limiting and MFA settings have been promoted to direct configuration parameters on `AquilaConfig.Auth`. Legacy Configuration (v1.3.0) Refactored Configuration (v1.3.1) --- 2. Replaced & Removed Decorators The legacy decorators `AdminGuard` and `VerifiedEmailGuard` have been removed. * **`AdminGuard`**: Replace with `@roles_required("admin")`. * **`VerifiedEmailGuard`**: Handle verification checks in your identity resolution backend (such as deactivating unverified users) or write a simple custom guard. Before: After: --- 3. Upgrading Flow Pipeline Guards All legacy guard adapters (historically located in `flow_guards.py`) have been removed. Use the new first-class guards directly. | Legacy Guard Class (v1.3.0) | Refactored Guard Class (v1.3.1) | |---|---| | `RequireAuthGuard` | `AuthGuard` | | `RequireRolesGuard` | `RoleGuard` | | `RequireScopesGuard` | `ScopeGuard` | | `RequirePolicyGuard` | `PolicyGuard` | Pipeline Registration Example Before: After: --- 4. Upgrading Session Guards The legacy `SessionGuard` class and `@requires` decorator in `aquilia.sessions.decorators` have been removed. Switch to the unified `PermissionEngine` and the unified `@requires` decorator. Before: After: --- 5. Removing the Fluent `AuthConfig` Builder If you set up custom authentication containers in testing or bootstrapping scripts using the `AuthConfig` builder, you must remove it. Configure integrations directly using dictionary payloads or the `AquilaConfig.Auth` classes. Before: After: --- 6. Deprecated APIs & Relocations * **`AuthManager.logout()`**: Deprecated in favor of `AuthManager.sign_out()`. Calling `logout()` now raises a `DeprecationWarning` but will invoke `sign_out()` internally for backward compatibility. * **`OptionalAuthMiddleware`**: Deprecated in favor of `AquilAuthMiddleware(require_auth=False)` or the new `AuthMiddleware` class. * **`RateLimiter` relocation**: The `RateLimiter` class has been moved from the `manager` module to `aquilia.auth.manager_types` to prevent circular imports. Update imports if you reference it directly. * **`ServiceScope` Enum class**: Deprecated in favor of plain string literals (e.g., `"singleton"`, `"app"`, `"request"`, `"transient"`, `"pooled"`, `"ephemeral"`) paired with `typing.Literal` type hints (`ServiceScopeLiteral`). Using `ServiceScope.SINGLETON` or other members will now emit a `DeprecationWarning`.

### Code Examples
```python
class auth(AquilaConfig.Auth):
    secret_key = Secret(env="AQ_SECRET_KEY", default="change-me")
    strategies = ["token", "session"]

```

```python
class auth(AquilaConfig.Auth):
    secret_key = Secret(env="AQ_SECRET_KEY", default="change-me")
    backends = [
        "aquilia.auth.backends.TokenBackend",
        "aquilia.auth.backends.SessionBackend",
    ]
    # Store type: "memory" or "redis"
    store_type = "memory"
    
    # Rate Limiting configuration parameters
    rate_limit_max_attempts = 5
    rate_limit_window_seconds = 900
    rate_limit_lockout_seconds = 3600
    
    # MFA settings
    mfa_enabled = False
    mfa_required = False
    
    # Clock skew tolerance (in seconds) for JWT validations
    clock_skew_seconds = 5
    
    # Audit trail activation
    audit_enabled = True

```

```python
from aquilia.auth import AdminGuard

@AdminGuard
async def delete_item(ctx):
    ...

```



---

## Release 1.3.1: Sessions
**URL**: `https://tubox.cloud/releases/1.3.1/sessions`

Session Security, AuthManager & RateLimiting Aquilia v1.3.1 introduces substantial security improvements to cookie-based and session-based authentication to prevent privilege escalation, alongside a refined `AuthManager` API and a standalone `RateLimiter` utility. --- 1. Session Serialization Hardening In previous versions of Aquilia, the full set of user roles, scopes, and attributes was serialized and stored directly inside the session store database (or client-side cookie): This optimization meant that if an administrator modified a user's permissions, suspended their account, or deleted them, the changes **would not take effect** for requests authenticated via session cookies until their session expired. In Aquilia v1.3.1, session serialization has been hardened. The `bind_identity` function only writes core identifiers: Notice that **roles, scopes, and user attributes are no longer written to the session store**. Active Identity Resolution * The `SessionBackend` captures the active session credentials. * It extracts the `identity_id` (either from `session.principal` or from `session.data["identity_id"]`). * It fetches a fresh `Identity` object directly from the `IdentityStore` on **every single request**. * Authorization guards evaluate roles and scopes against this fresh database/cache state. --- 2. Shared Manager Types: `RateLimiter` To protect brute-force paths (such as username/password login), Aquilia v1.3.1 introduces a standalone `RateLimiter` class in `aquilia.auth.manager_types` (and re-exported in `aquilia.auth.manager` for backward compatibility). * **Constructor & Parameters**: Tracks failed authentication attempts per key (typically a username or IP address) within a sliding time window. * **Core API Methods**: * `record_attempt(key: str) -> None`: Records a failed attempt. If attempts exceed `max_attempts` within the window, locks out the key. * `is_locked_out(key: str) -> bool`: Checks if the key is currently locked out. * `get_remaining_attempts(key: str) -> int`: Returns attempts left before lockout. * `reset(key: str) -> None`: Clears attempt history for the key on successful authentication. --- 3. `AuthManager` Refactored APIs The `AuthManager` class (defined in `aquilia.auth.manager`) is the central coordinator for authentication operations. The following APIs were updated: Token Revocation The token revocation API now supports access tokens by extracting the unique JWT identifier (`jti`) and blacklisting it: * `async def revoke_token(self, token: str, token_type: str = "refresh") -> None`: * If `token_type == "refresh"`, revokes the refresh token directly. * If `token_type == "access"`, validates the access token, extracts the `jti` claim, and revokes it so subsequent validations reject it. Deprecated `logout()` * **Signature**: `async def logout(self, identity_id=None, session_id=None, access_token=None, refresh_token=None) -> None` * **Status**: **Deprecated** in favor of `sign_out()`. Raises a `DeprecationWarning` when called. --- 4. `SessionAuthBridge` The `SessionAuthBridge` coordinates actions between `AuthManager` and `SessionEngine`: * `create_auth_session(identity, request, token_claims=None)`: Resolves and binds authentication credentials to a new session. * `rotate_on_privilege_escalation(session, response)`: Rotates the session ID (session fixation protection) after an escalating event (such as completing an MFA challenge). * `logout(session, response)`: Destroys the current session. * `logout_all_devices(identity_id)`: Revokes and purges all active session identifiers linked to a given identity ID across the session store.

### Code Examples
```python
# Old, insecure v1.3.0 implementation:
session["roles"] = identity.get_attribute("roles", [])
session["scopes"] = identity.get_attribute("scopes", [])
session["status"] = identity.status.value

```

```python
# Hardened v1.3.1 implementation:
session.mark_authenticated(AuthPrincipal.from_identity(identity))
session["identity_id"] = identity.id
if identity.tenant_id is not None:
    session["tenant_id"] = identity.tenant_id

```

```python
def __init__(
      self,
      max_attempts: int = 5,
      window_seconds: int = 900,
      lockout_duration: int = 3600,
  )
  
```



---

## Aquilia Performance & Benchmark
**URL**: `https://tubox.cloud/benchmark`

import from 'lucide-react' interface ScenarioMetric interface WebSocketMetric interface FrameworkBenchmark websocket: WebSocketMetric scenarios: ScenarioMetric[] } interface BenchmarkRun methodology: string[] profile: frameworks: FrameworkBenchmark[] } const benchmarkRun: BenchmarkRun = , methodology: [ 'All frameworks ran with a single server process via Uvicorn on localhost.', 'Each HTTP scenario used scenario-specific warmup, then measured throughput and latency percentiles.', 'CPU and RSS memory were sampled during each scenario.', 'WebSocket benchmark used echo round trips where supported.', 'Flask is treated as WebSocket unsupported in this suite (no extra extension stack).', ], profile: , frameworks: [ , websocket: , scenarios: [ , , , , , , , , , , , , , , , , , , ], }, , websocket: , scenarios: [ , , , , , , , , , , , , , , , , , , ], }, , websocket: , scenarios: [ , , , , , , , , , , , , , , , , , , ], }, ], } function titleCase(value: string): string function formatScenario(value: string): string function formatNumber(value: number): string ) } setIsSidebarOpen(true)} /> setIsSidebarOpen(false)} /> Benchmark Report Aquilia vs FastAPI vs Flask Comprehensive benchmark from run , covering startup, 18 HTTP scenarios, WebSocket throughput, CPU/RSS process sampling, and failure rates. Overall Leader req/s mean throughput Run Profile base requests concurrency | warmup Environment CPU cores HTTP Winners Aquilia: scenarios FastAPI: scenarios Flask: scenarios Performance Charts , , , , , , ].map((chart) => ( ))} Startup and Aggregate Summary Framework Startup (s) Mean Throughput (req/s) Mean P95 (ms) Failure Rate (%) ))} WebSocket Results Framework Throughput (msg/s) P95 (ms) Failures ) ) : ( )} ) })} Methodology and Interpretation ))} This page reflects the latest balanced run in this repository. For confidence intervals, compare across multiple runs in benchmark/results and report median plus spread. Detailed HTTP Scenarios 18 scenario matrix including throughput, latency bands, failure count, and sampled process cost. Scenario Requests Throughput P50 P95 P99 Failures Avg CPU % Peak RSS MB ))} ))} Artifacts and Reproducibility Run directory benchmark/results/ Primary files results.json and report.md Back to Home Open Documentation Release Timeline )


---

## Aquilia Changelogs
**URL**: `https://tubox.cloud/changelogs`

import from 'lucide-react' interface ChangelogSection interface ChangelogEntry const staticChangelogs: ChangelogEntry[] = [ , , , , ] }, ] }, ] }, , , , ] }, ] }, , ] }, , ] }, , ] }, , ] }, ] }, ] } ] const tagColors: Record = const typeColors: Record = , changed: , fixed: , security: , breaking: , removed: } // Parser to parse CHANGELOG.md into ChangelogEntry[] function parseMarkdownChangelog(md: string): ChangelogEntry[] ) } } // Construct summary from first few items or sections const firstSection = sections[0] let summaryText = `Release details for v$ .` if (firstSection && firstSection.items.length > 0) else } // Determine tag based on version const parts_v = version.split('.') const tag = parts_v[0] !== '0' && parts_v[1] === '0' && parts_v[2] === '0' ? 'major' : parts_v[2] === '0' ? 'minor' : 'patch' entries.push( ) } return entries } // Render helper to parse inline markdown bold (**) and code (`) tags, coloring them with Aquilia green function renderFormattedText(text: string, isDark: boolean): React.ReactNode ); } return ; }); if (isBold) ); } return ; }); } interface ContentBlock function cleanCodeIndentation(lines: string[]): string function parseItemContent(text: string): ContentBlock[] ) currentLines = [] } inCodeBlock = true currentLanguage = trimmedLine.slice(3).trim() || 'python' } } else } if (currentLines.length > 0) ) } else ) } } return blocks } function renderItemWithCodeBlocks(item: string, isDark: boolean): React.ReactNode const paragraphs = (block.content || '').split(/\n\n+/) return ( ) })} ) })} ) } export function Changelogs( : ) = useTheme() const isDark = theme === 'dark' const version = useVersion() const [isSidebarOpen, setIsSidebarOpen] = useState(false) const [activeFilter, setActiveFilter] = useState (null) const [expandedVersions, setExpandedVersions] = useState >( printMode ? staticChangelogs.reduce((acc, entry) => ( ), ) : ) const [changelogData, setChangelogData] = useState (printMode ? staticChangelogs : []) const [isLoading, setIsLoading] = useState(!printMode) const schema = , , ] } ] } useEffect(() => ) .then(text => ) } setIsLoading(false) }) .catch(err => ) setIsLoading(false) }) }, [version, printMode]) const toggleVersion = (version: string) => )) } const filteredChangelogs = changelogData.map(entry => }).filter(entry => entry.sections.length > 0 || !activeFilter) if (printMode) } return ( ))} ) })} )} ))} ) } return ( setIsSidebarOpen(true)} /> setIsSidebarOpen(false)} /> Changelog A comprehensive, sequential log of all additions, changes, and fixes across the Aquilia core framework and libraries. Filter logs: All ))} } return ( ))} ) })} )} ) })} )} Keep a Changelog Aquilia follows semantic versioning rules (`vMajor.Minor.Patch`) and tracks modifications according to Keep a Changelog guidelines. Quick Links View Releases Documentation GitHub Repository )


---

## Aquilia Help & Support
**URL**: `https://tubox.cloud/help`

Support / Troubleshooting Help Center Encountered an issue or have questions about the Aquilia framework? Our developer resources are designed to get you unblocked quickly. Official Support Channels Report an Issue Found a bug or incorrect compiler behavior? Raise an issue on our GitHub repository with reproduction steps. Join GitHub Discussions Have a question about DI scopes, session adapters, or custom URL routing? Start a thread or seek advice from the community. Frequently Encountered Errors ScopeViolationError This occurs when a SINGLETON scoped service attempts to inject a REQUEST or transient scoped dependency in its constructor. Ensure constructor injections match or use a factory method instead. PatternSyntaxError Triggered if your URL parameter syntax is malformed. Ensure you use the updated curly brace format (e.g. "}) and not the legacy chevron tags. )


---

## Aquilia Community
**URL**: `https://tubox.cloud/community`

Connect / Build Community Space Join our growing community of developers building production-grade asynchronous web applications, database pipelines, and APIs with Aquilia. Community Hubs GitHub Discussions Share projects, request comments, post RFCs, and collaborate with other developers. Open Source Repository Explore the Python framework implementation, clone the repository, run test pipelines, or submit Pull Requests. How to Contribute We welcome code contributions, performance optimizations, custom middlewares, and documentation updates. Read our contribution guide on GitHub to set up your environment, write tests using pytest, and follow the pre-commit checks. )


---

## Aquilia Privacy Policy
**URL**: `https://tubox.cloud/privacy`

Legal / Compliance Privacy Policy Last updated: July 06, 2026 1. Overview & Scope Aquilia Framework is committed to protecting the privacy of developers visiting our documentation site. This Privacy Policy details the types of data we process, our purposes for doing so, and the controls available to you. 2. Cookie Preferences & Granular Consent We employ a cookie preference panel enabling you to toggle non-essential cookies. Below is an overview of cookie categories used on this site: Essential Cookies: Used exclusively to preserve critical preferences, such as your theme state (dark/light mode) and whether you have acknowledged our compliance statements. These cannot be disabled as the site cannot function properly without them. Analytics Cookies: Help us measure documentation usage (e.g., page views, scroll depth, and search query trends). You can toggle these cookies on or off through the Customize popup. Marketing / Notification Cookies: Used optionally to tailor announcements, framework update rollouts, and community newsletters. 3. Server Logs & Hosting Environments This documentation is served statically. The hosting infrastructure provider (such as GitHub Pages or Vercel) may log standard network requests, including IP addresses, browser user-agents, and request timestamps. These logs are processed by the hosting provider for security purposes, network routing, and DDoS mitigation under their respective privacy policies. We do not store or import these raw connection logs. 4. Developer Controls & Rights As a visitor, you have full control over your browser data. You can clear your cookies, disable local storage, or modify your cookie consent choices at any time. Under regional frameworks like GDPR or CCPA, you have the right to visit our site without being tracked, which is why all analytics and marketing cookies remain disabled by default until you explicitly opt-in. 5. Contact & Feedback If you have any questions or concerns regarding our privacy controls, please contact our maintainers or open a thread in the community discussions on GitHub. )


---

## Aquilia Terms of Service
**URL**: `https://tubox.cloud/terms`

Legal / Terms of Use Terms & Conditions Last updated: July 06, 2026 WARNING: Template Content This page is a starting-point template, not legal advice. Have qualified legal counsel review and adapt it before relying on it for a production site. Conditions for using the Aquilia documentation site. Template content — review with qualified legal counsel before production use. 1. Acceptable Use The Aquilia documentation is provided for reference and educational purposes. You agree not to misuse the site, attempt to disrupt it, or use it in violation of applicable law. 2. Intellectual Property The Aquilia framework is published under the license stated in its repository. The documentation content on this site is provided to support that framework; trademarks, logos, and brand elements remain the property of their respective owners. 3. Warranty Disclaimer The documentation is provided "as is", without warranty of any kind, express or implied, including warranties of merchantability, fitness for a particular purpose, and non-infringement. 4. Limitation of Liability To the maximum extent permitted by law, in no event will the project, its maintainers, or its contributors be liable for any indirect, incidental, special, consequential or punitive damages arising out of or related to use of this site. )


---

## Framework Docs: GUIDE.md
**URL**: `https://tubox.cloud/docs/framework/GUIDE`

Aquilia Framework — Complete Usage Guide > **Version:** 1.1.0 > **Python:** 3.12+ > **Architecture:** ASGI-native, modular, DI-first --- Table of Contents 1. [Getting Started](#1-getting-started) 2. [Workspace & Modules](#2-workspace--modules) 3. [Controllers](#3-controllers) 4. [Dependency Injection](#4-dependency-injection) 5. [Configuration](#5-configuration) 6. [Sessions](#6-sessions) 7. [Authentication & Authorization](#7-authentication--authorization) 8. [Faults (Error Handling)](#8-faults-error-handling) 9. [WebSockets](#9-websockets) 10. [Templates](#10-templates) 11. [Models & ORM](#11-models--orm) 12. [Effects](#12-effects) 13. [URL Patterns](#13-url-patterns) 14. [Middleware](#14-middleware) 15. [Lifecycle Management](#15-lifecycle-management) 16. [Request & Response](#16-request--response) 17. [Debug Pages](#17-debug-pages) 18. [CLI Reference](#18-cli-reference) 19. [Testing](#19-testing) 20. [Deployment](#20-deployment) 21. [Server-Sent Events (SSE)](#21-server-sent-events-sse) 22. [OpenTelemetry](#22-opentelemetry) 23. [Request Body Validation](#23-request-body-validation) --- 1. Getting Started Installation Create a Workspace This generates: Add a Module Creates: Run the Server The server starts at `http://127.0.0.1:8000`. In debug mode, a welcome page appears at `/`. --- 2. Workspace & Modules Workspace Configuration (`workspace.py`) The workspace is the **root of your application**. It defines: - Which modules are loaded - Which integrations are active - Session, security, and telemetry settings Module Manifests (`manifest.py`) Each module has a manifest that declares its components: --- 3. Controllers Controllers are the HTTP layer. They handle requests and return responses. Basic Controller Route Decorators | Decorator | HTTP Method | Example | |-----------|-------------|---------| | `@GET(path)` | GET | `@GET("/users")` | | `@POST(path)` | POST | `@POST("/users")` | | `@PUT(path)` | PUT | `@PUT("/users/{id:int}")` | | `@PATCH(path)` | PATCH | `@PATCH("/users/{id:int}")` | | `@DELETE(path)` | DELETE | `@DELETE("/users/{id:int}")` | | `@HEAD(path)` | HEAD | `@HEAD("/health")` | | `@OPTIONS(path)` | OPTIONS | `@OPTIONS("/users")` | | `@WS(path)` | WebSocket | `@WS("/live")` | | `@route(path, methods=[...])` | Multiple | `@route("/data", methods=["GET", "POST"])` | RequestCtx Every handler receives a `RequestCtx` with: Lifecycle Hooks Controllers support lifecycle hooks for setup/teardown: Controller Pipeline Attach middleware/guards at the controller level: Template Rendering Controllers can render templates: --- 4. Dependency Injection Aquilia's DI system supports automatic constructor injection, multiple scopes, and provider types. Marking Services Scopes | Scope | Description | |-------|-------------| | `singleton` | One instance for entire application lifetime | | `app` | One instance per application (alias for singleton in most cases) | | `request` | New instance per HTTP request | | `transient` | New instance every time it's resolved | | `pooled` | Instance from a pre-allocated pool | | `ephemeral` | Ultra-short-lived, no caching | Constructor Injection Dependencies are resolved by type from constructor parameters: Using `Inject` for Fine Control Factory Providers Provider Types | Provider | Use Case | |----------|----------| | `ClassProvider` | Auto-resolves constructor deps from type hints | | `FactoryProvider` | Custom factory function | | `ValueProvider` | Fixed value (configs, constants) | | `PoolProvider` | Pre-allocated pool of instances | | `AliasProvider` | Alias one token to another | | `LazyProxyProvider` | Lazy-initialized on first access | | `ScopedProvider` | Provides different implementations per scope | Controller DI Controllers automatically get dependencies injected via their constructor: Testing with DI --- 5. Configuration YAML Configuration **`config/base.yaml`** — Shared defaults: **`config/dev.yaml`** — Development overrides: **`config/prod.yaml`** — Production: Accessing Configuration Python Configuration (Workspace Builder) --- 6. Sessions Session Policy Session Stores | Store | Description | |-------|-------------| | `MemoryStore` | In-memory (development) | | `FileStore` | File-backed with variants: `.web_optimized()`, `.api_optimized()`, `.mobile_optimized()` | Session Transports | Transport | Usage | |-----------|-------| | `CookieTransport` | Browser sessions via cookies | | `HeaderTransport` | API clients via `X-Session-ID` header | Using Sessions in Controllers Typed Session State Session Decorators | Decorator | Effect | |-----------|--------| | `@session.require(authenticated=True)` | Requires an active, authenticated session | | `@session.ensure()` | Creates session if none exists | | `@authenticated` | Shortcut for requiring authentication | | `@stateful` | Marks handler as stateful (session-dependent) | Session Guards Session Context Manager --- 7. Authentication & Authorization Identity Every authenticated request has an `Identity`: Credentials Au

### Code Examples
```python
pip install aquilia

```

```python
aq init workspace myapp
cd myapp

```

```python
myapp/
├── workspace.py          # Workspace structure (modules, integrations)
├── starter.py            # Welcome page (auto-loaded in debug mode)
├── config/
│   ├── base.yaml         # Shared defaults
│   ├── dev.yaml          # Development settings
│   └── prod.yaml         # Production settings
├── modules/              # Application modules
├── templates/            # Jinja2 templates
├── artifacts/            # Build artifacts
└── runtime/              # Runtime state

```



---

## Framework Docs: README.md
**URL**: `https://tubox.cloud/docs/framework/README`

<div align="center"> <img src="assets/logo.png" alt="Aquilia Logo" width="200" /> <h1>Aquilia</h1> <p><strong>The Python framework for teams building production APIs. Write controllers and services. Aquilia discovers everything, manages its own architecture, and deploys itself.</strong></p> [![Version](https://img.shields.io/badge/version-1.2.1-blue.svg)](https://tubox.cloud) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) [![Tests](https://img.shields.io/badge/tests-5085%20passing-brightgreen.svg)](#-testing) </div> *** Introduction Aquilia is the Python framework for teams building production APIs. Write controllers and services. Aquilia discovers everything, manages its own architecture, and deploys itself. You do not touch most framework-managed files. Write your controllers and services. Run `aq serve`. Aquilia handles routing, discovery, dependency injection, manifests, runtime orchestration, Docker integration, deployment tooling, and application wiring automatically. *** Architecture Decouple your application code from runtime orchestration. The system is split into three main components: developer space, framework engine, and infrastructure templates. ![Aquilia High-Level System Architecture](assets/architecture/high_level.svg) *** Who is it for? Aquilia is built for backend engineers and product teams who have outgrown the ad-hoc patterns of small web libraries. If you are tired of writing routing boilerplate, manually stitching dependency trees, wrestling with ASGI lifespans, or maintaining custom Dockerfiles, Aquilia provides a clean, self-organizing architecture. Why does it exist? Most Python web frameworks follow a microframework design. While this is great for small scripts, it falls apart in large codebases. Teams end up creating their own framework layers for database transactions, configuration loading, caching, versioning, and dependency injection. These layers are rarely documented, hard to test, and lead to maintenance debt. Aquilia replaces this custom glue code with standard, convention-driven structures. Comparison Against Flask and FastAPI Flask and FastAPI are microframeworks. They require you to manually import and wire every router, database connection pool, and service instantiation. As your codebase grows, this leads to large, fragile import loops. Aquilia is different. You declare your controllers and services, and Aquilia discovers and wires them automatically. Comparison Against NestJS Aquilia is closer to NestJS for Python. It uses a structured, modular design where folders represent logical boundaries (modules). Modules declare their components (controllers and services) inside a manifest file, and the framework orchestrates dependency injection, middleware ordering, and lifecycle hooks automatically. *** Philosophy Convention over Configuration We believe developers should focus on business logic rather than wiring code. Aquilia sets logical defaults for directory structures, routing, configuration caching, and environment variables. If you follow the folder structure, everything works out of the box. Automatic Discovery Manual route registration is a common source of bugs and circular imports. Aquilia uses a Package Scanner to inspect your workspace, identify manifests, import modules, and register endpoints. Self-Managing Architecture The framework builds a topological dependency graph at startup. It detects circular references before your application starts, manages request-scoped lifecycles, and automatically compiles your code into optimized deployment manifests. Production-First Design Aquilia comes with production essentials built in: * Scoped dependency injection with singleton, app, and request scopes. * A structured fault handling system that replaces unhandled tracebacks with typed error domains. * Declarative multi-dimensional security clearances. * API versioning with RFC-compliant sunset warning headers. *** Quick Start 1. Install the Core and Server Adapters Install the base framework along with the production server package: 2. Scaffold a Workspace Create a new workspace using the CLI: This generates your workspace root containing `workspace.py`, a `config/` folder, and a default module. 3. Add a Module Add a user management module: This creates the following structure: 4. Run the Development Server Start the server with hot reloading enabled: Your API is now running on `http://127.0.0.1:8000`. *** Developer Workflow What Files You Write As a developer, you only write code inside your modules: * **Controllers** (`controllers.py`): Define your HTTP and WebSocket endpoints using route decorators. * **Services** (`services.py`): Implement business logic, database operations, and external API calls. * **Models** (`models.py`): Declare your database schema using the pure Python ORM. * **Contracts** (`contracts.py` or inline): Define input and out

### Code Examples
```python
pip install "aquilia[full]"

```

```python
aq init workspace my-api
cd my-api

```

```python
aq add module users

```



---

## Framework Docs: CHANGELOG.md
**URL**: `https://tubox.cloud/docs/framework/CHANGELOG`

Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). [1.3.3] — 2026-07-21 — "Analytical Depths" Added ORM — Window Function Support (`aquilia.models.window`) - **`Window(expression, *, partition_by, order_by, frame)`** — first-class `OVER (...)` expression. Wraps any aggregate or window function with a full window clause. Integrates with `annotate()`, `order_by()`, `values()`, and `values_list()` without restrictions. - **Ranking functions**: `Rank()` → `RANK()`, `DenseRank()` → `DENSE_RANK()`, `RowNumber()` → `ROW_NUMBER()`. - **Distribution**: `Ntile(n)` → `NTILE(n)`. - **Offset functions**: `Lag(expr, offset=1, default=None)` → `LAG(expr, offset[, default])`, `Lead(expr, offset=1, default=None)` → `LEAD(expr, offset[, default])`. - **Value access**: `FirstValue(expr)` → `FIRST_VALUE(expr)`, `LastValue(expr)` → `LAST_VALUE(expr)`, `NthValue(expr, n)` → `NTH_VALUE(expr, n)`. - **Aggregate windows**: Any existing aggregate (`Sum`, `Avg`, `Count`, `Max`, `Min`) can be used directly inside `Window(...)` for running totals, cumulative averages, etc. - **Frame clauses** via `WindowFrame(frame_type, start, end)` + `FrameBound` helpers (`FrameBound.unbounded_preceding()`, `FrameBound.current_row()`, `FrameBound.unbounded_following()`, `FrameBound.preceding(n)`, `FrameBound.following(n)`). Frame types: `FrameType.ROWS`, `FrameType.RANGE`, `FrameType.GROUPS`. - **Partition**: `partition_by` accepts `str`, `F()`, or a list of either — rendered as quoted identifiers. - **Ordering**: `order_by` inside the window accepts `str` (prefix `-` for DESC), `OrderBy`, or a list of both. - Full `as_sql(dialect)` support across SQLite 3.25+, PostgreSQL 8.4+, MySQL 8.0+. ORM — CTE Support (`aquilia.models.cte`) - **`Q.cte(name)`** — creates a `CTE` object from any queryset. Non-executing; wraps the queryset's compiled SQL as a named CTE. - **`Q.with_cte(*ctes)`** — registers one or more `CTE` or `RecursiveCTE` objects. Chains additively. Automatically promotes preamble to `WITH RECURSIVE` when any recursive CTE is present. - **`CTE`** class — represents `name AS (SELECT ...)`. Call `.col('field')` to get a `CTECol` expression reference for use inside other queries. - **`CTECol(cte_name, column)`** — `Expression` subclass rendering `"cte_name"."column"`, for referencing CTE columns in filters and annotations. - **`CTEReference`** — used inside recursive lambda to reference the CTE itself. Supports `.col('field')` returning `CTECol`. ORM — Recursive CTE Support (`aquilia.models.cte`) - **`Q.recursive_cte(name, anchor, recursive, *, union_all=True)`** — high-level API for `WITH RECURSIVE`. Accepts: - `anchor`: lambda `(Q) → Q` — the base, non-recursive term. - `recursive`: lambda `(CTEReference) → Q` — the recursive term; use `cte_ref.col('id')` for self-referential joins. - `union_all`: `True` (default) for `UNION ALL`, `False` for deduplicating `UNION`. - Supports tree traversal (folder trees, comment trees, org charts), dependency graphs, and category hierarchies. - **`RecursiveCTE`** class — renders as `name AS (anchor UNION [ALL] recursive_part)`. - CTE parameters are prepended before annotation and WHERE parameters in the final bind list, preserving correct positional order. - Cyclic-guard: the SQL engine handles cycle termination natively; Aquilia emits the correct `WITH RECURSIVE` syntax. ORM — Bug Fixes (from audit in this release) - **`UUIDField(auto=True)` NULL insert bug**: `setdefault` on pre-populated `kwargs` dict was a no-op. Fixed to explicit `UNSET` sentinel check — `auto=True` fields now always generate a UUID default, never `NULL`. - **Transaction nesting depth tracker memory leak and `id()` reuse contamination**: Replaced `WeakValueDictionary` keyed on `id(task)` with a `contextvars.ContextVar[int]` — consistent with all other Aquilia subsystems, leak-free, and isolation-safe under `asyncio.gather()`. ORM — Security & Concurrency Hardening (from senior-engineer assessment) - **Widened raw-SQL safety guard on `Q.where()`/`Q.having()`** (`aquilia/models/query.py`): both methods previously used two separate, inconsistent keyword blocklists — `where()` only rejected `DROP/ALTER/TRUNCATE/EXEC/EXECUTE` via a trailing-space substring match (vulnerable to false positives like `"AIRDROP "`), `having()` had a wider-but-still-incomplete set and no word-boundary matching. Replaced both with one shared, word-boundary regex guard (`_reject_unsafe_clause`) that additionally blocks `DELETE`, `INSERT`, `UPDATE`, `MERGE`, SQL comment markers (`--`, `/*`, `*/`), and bare `;` (statement-stacking). A column literally named `updated_at` no longer false-positives on `UPDATE`. This is a secondary guardrail, not the actual injection defense — parameter binding remains the real protection; the guard only catches unparameterized raw clauses. - **`

### Code Examples
```python
from aquilia import Controller, GET, Attributes, RequestCtx

  class ProductsController(Controller):
      attr = (
          Attributes()
          .prefix("/products")
          .tags("Products")
          .pipeline(AuthPipeline)
          .instantiation_mode("singleton")
          .timeout(30.0)
          .max_body_size(4096)
      )

      @GET("/")
      async def list_products(self, ctx: RequestCtx):
          ...
  
```

```python
message: str = Field(...)  # translates to required=True, default=UNSET
    
```

```python
message: str = Field(...)  # translates to required=True, default=UNSET
    
```



---

## Framework Docs: CHANGES.md
**URL**: `https://tubox.cloud/docs/framework/CHANGES`

Swarm Change Log Autonomous Sequential Commit Swarm — every modification is recorded here. --- Session Bootstrap Timestamp: boot Agent: system Summary: Initialized swarm infrastructure and change log. Commit Hash: N/A (bootstrap) Commit 1 Timestamp: 2026-06-08T00:00:00Z Agent: system Files Modified: - .swarm/__init__.py - .swarm/agents/__init__.py - .swarm/state.json - .swarm/tasks.json - CHANGES.md Summary: Created swarm directory structure and bootstrap files. Commit Hash: 6575397 Commit 2 Timestamp: 2026-06-08T00:01:00Z Agent: system Files Modified: - .gitignore Summary: Removed .swarm/ from gitignore to track swarm artifacts. Commit Hash: 8e4ffab Commit 3 Timestamp: 2026-06-08T00:02:00Z Agent: system Files Modified: - .swarm/state.py - CHANGES.md Summary: Added state management module with atomic persistence, checkpoint creation/restoration, and session initialization. Commit Hash: ac7d637 Commit 4 Timestamp: 2026-06-08T00:03:00Z Agent: system Files Modified: - .swarm/agents/base.py Summary: Added agent base class with Message envelope format, AgentType and MessageType enums, and inter-agent communication protocol. Commit Hash: 25a8d4c Commit 5 Timestamp: 2026-06-08T00:04:00Z Agent: system Files Modified: - .swarm/agents/planner.py Summary: Added Planner Agent that decomposes user requests into ordered atomic tasks with dependencies. Commit Hash: d315ca6 Commit 6 Timestamp: 2026-06-08T00:05:00Z Agent: system Files Modified: - .swarm/agents/commit.py Summary: Added Commit Agent with structured commit message format generation and git commit execution. Commit Hash: ac59d9b Commit 7 Timestamp: 2026-06-08T00:06:00Z Agent: system Files Modified: - .swarm/agents/changelog.py Summary: Added Change Log Agent with append-only CHANGES.md maintenance. Commit Hash: 6ed7638 Commit 8 Timestamp: 2026-06-08T00:07:00Z Agent: system Files Modified: - .swarm/agents/review.py Summary: Added Review Agent that validates code changes via ruff before commits. Commit Hash: 1b539b2 Commit 9 Timestamp: 2026-06-08T00:08:00Z Agent: system Files Modified: - .swarm/agents/test.py Summary: Added Test Agent that runs ruff lint/format checks and pytest. Commit Hash: f4d544a Commit 10 Timestamp: 2026-06-08T00:09:00Z Agent: system Files Modified: - .swarm/agents/worker.py Summary: Added Worker Agent with full sequential commit protocol pipeline: implement -> review -> test -> commit -> changelog. Commit Hash: 36afd5e Commit 11 Timestamp: 2026-06-08T00:10:00Z Agent: system Files Modified: - .swarm/agents/coordinator.py Summary: Added Coordinator Agent for dynamic worker spawning, dependency-based task assignment, and commit verification. Commit Hash: de01e08 Commit 12 Timestamp: 2026-06-08T00:11:00Z Agent: system Files Modified: - .swarm/recovery.py Summary: Added recovery system with checkpoint/rollback, task retry (max 3), and crash-resume support. Commit Hash: 149037a Commit 13 Timestamp: 2026-06-08T00:12:00Z Agent: system Files Modified: - .swarm/engine.py Summary: Added execution engine with CLI interface (status, execute, tasks, resume) and programmatic API. Commit Hash: 3dd6fd9 Commit 14 Timestamp: 2026-06-08T00:13:00Z Agent: system Files Modified: - .swarm/__init__.py - .swarm/agents/__init__.py Summary: Wired together all exports with architecture documentation and complete public API surface. Commit Hash: ef5f7e0 Commit 15 Timestamp: 2026-07-05T22:58:00Z Agent: Antigravity Files Modified: - aquilia/integrations/admin.py - aquilia/integrations/integration.py Summary: - Fixed flat legacy configuration compatibility in Integration.admin(**kwargs) by properly parsing and extracting all modules and sub-config attributes. - Added property descriptors and __slots__ support in AdminModules for _mailer and _testing flags. - Implemented bytecode scan-forward detection for active attribute function calls in LegacyFluentMixin.__getattribute__ to dynamically return callable wrappers only when the attributes are invoked as methods, allowing direct attributes to resolve to their primitive Python values to support 'is True'/'is False' assertions. - Added attribute bounds validation/clamping in AdminSecurity.__setattr__ and AdminSecurity.__post_init__ for csrf_max_age, csrf_token_length, rate_limit_max_attempts, rate_limit_window, password_min_length, and event_tracker_max_events. - Corrected database default url to sqlite:///db.sqlite3 in Integration.database().


---

## Framework Docs: SECURITY.md
**URL**: `https://tubox.cloud/docs/framework/SECURITY`

Security Policy Supported Versions Currently, the following versions of Aquilia are supported with security updates. We recommend always running the latest version. | Version | Supported | | ------- | ------------------ | | 1.0.2 | :white_check_mark: | | 1.0.0 | :warning: upgrade recommended | | < 1.0 | :x: | Security Audit Status Aquilia v1.0.2 has undergone a comprehensive 15-phase security audit covering all subsystems: | Subsystem | Status | Key Protections | |-----------|--------|----------------| | **Core/Server** | ✅ Audited | Header injection prevention, ASGI lifecycle hardening | | **Auth** | ✅ Audited | Argon2 hashing, JWT rotation, CSRF double-submit, MFA, rate limiting | | **DI** | ✅ Audited | Scope isolation, cycle detection, provider leak prevention | | **Controller** | ✅ Audited | Filter/pagination injection protection | | **Sessions** | ✅ Audited | Fixation protection, secure cookie flags, transport hardening | | **Contracts** | ✅ Audited | Namespace collision prevention, annotation validation | | **ORM/Models** | ✅ Audited | Parameterized queries, field validation, SQL injection prevention | | **Admin** | ✅ Audited | RBAC, audit logging, CSRF, rate-limiting, input sanitization | | **Storage** | ✅ Audited | Path traversal blocking, null byte rejection, Fault-based errors | | **Tasks** | ✅ Audited | Registered-task-only resolution, no arbitrary code execution | | **Templates** | ✅ Audited | Sandboxed Jinja2, HMAC-verified bytecode cache, autoescape | | **Faults** | ✅ Audited | 14 typed domains, no raw exceptions in any audited subsystem | Critical Fixes in v1.0.2 1. **Unsafe pickle deserialization** — `templates/bytecode_cache.py` and `templates/manager.py` previously used `pickle.load()` to deserialize cached template data from disk. This has been replaced with HMAC-verified JSON serialization (SHA-256 signature) to prevent arbitrary code execution via tampered cache files. 2. **Path traversal in storage** — `storage/base.py._normalize_path()` now rejects null bytes (`\x00`), `..` path segments after normalization, and paths exceeding 1024 characters. 3. **Arbitrary task execution** — `tasks/engine.py._execute_job()` previously resolved `func_ref` strings via `importlib`, potentially allowing arbitrary code execution if job metadata was tampered with. Resolution now only uses the registered `@task` decorator registry. 4. **SQL injection vectors** — ORM expression engine and lookup system now use parameterized queries throughout, with field name validation rejecting special characters. Reporting a Vulnerability Security is a high priority for the Aquilia project and its community. If you discover a security vulnerability in Aquilia, please adhere to the following guidelines: 1. **Do NOT open a public issue.** This gives attackers an opportunity to exploit the vulnerability before an official patch is released. 2. Please send an email to the project maintainers outlining the vulnerability context and potential steps to reproduce. 3. We will acknowledge receipt of your vulnerability report as soon as possible and strive to send you regular updates about our progress. 4. Once the issue has been resolved and a new release is available, we will announce the fix publicly and give you credit for the discovery (unless you prefer to remain anonymous). Scope This policy applies to all core components included in the `aquilia` distribution package. If the vulnerability affects a third-party module or dependency, you should report it directly to that upstream project, but notifying us is still appreciated so we can update our dependencies as well. Security-Related Dependencies | Dependency | Purpose | Minimum Version | |-----------|---------|----------------| | `cryptography` | JWT, token signing | ≥42.0.0 | | `argon2-cffi` | Password hashing | ≥23.1.0 | | `jinja2` | Template sandboxing | ≥3.1.0 | | `markupsafe` | XSS prevention (autoescape) | ≥2.1.0 |


---

## Framework Docs: CONTRIBUTING.md
**URL**: `https://tubox.cloud/docs/framework/CONTRIBUTING`

Contributing to Aquilia First off, thank you for considering contributing to Aquilia! It's people like you that make Aquilia such a great tool. Below are the guidelines and steps to contribute to the project. Code of Conduct This project and everyone participating in it is governed by the [Aquilia Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Submitting Contributions 1. Find an Issue to Work On Check our [issue tracker](https://github.com/tubox-labs/Aquilia/issues) on GitHub. Issues labeled `good first issue` or `help wanted` are great places to start. 2. Fork & Branch Fork the repository on GitHub and clone it locally. Then, create a new branch for your work: or 3. Local Development Setup Aquilia requires Python 3.10 or higher. We recommend using a virtual environment: Install the dependencies, including the development ones: 4. Making Changes Make your code changes, following our style guides. * Aquilia adopts standard Python PEP 8 style formatting. * We recommend using `ruff` for linting and formatting. * Ensure all your changes are typed properly. * **Use structured Faults, not raw exceptions.** All errors should use `aquilia.faults.core.Fault` subclasses with proper domain, code, and severity. See `aquilia/faults/domains.py` for examples. 5. Fault System Guidelines When adding error handling to any subsystem: - Create fault classes in a `faults.py` module within the subsystem - Use `FaultDomain.custom("name", "description")` for new domains - Every fault must have a stable `code` (e.g., `"TASK_SCHEDULE_INVALID"`), descriptive `message`, and appropriate `severity` - Never raise raw `ValueError`, `RuntimeError`, `TypeError`, or `KeyError` — wrap them in a Fault subclass - See existing examples: `aquilia/tasks/faults.py`, `aquilia/storage/base.py`, `aquilia/templates/faults.py`, `aquilia/admin/faults.py` 6. Security Guidelines - Never use `pickle.load()` or `pickle.loads()` on untrusted data — use JSON with HMAC verification - Always validate and normalize file paths (null bytes, `..` traversal, length limits) - Use parameterized queries — never interpolate user input into SQL strings - Template rendering must use `SandboxedEnvironment` with autoescape enabled - Background task resolution must only use the registered task registry 7. Testing Before submitting, run our test suite using `pytest`: The full suite has 5,085+ tests and should complete in under 60 seconds. Ensure all tests pass and consider adding new tests to cover any new logic or edge cases you introduce. Use `pytest --cov=aquilia` to check coverage. 8. Submit a Pull Request Push your branch to your forked repository and submit a Pull Request against the `master` branch. Provide a clear description of the problem your PR solves or feature it adds. Reporting Bugs - Make sure you are on the latest version of Aquilia. - Provide a clear and descriptive title. - Describe the exact steps which reproduce the problem in as many details as possible. - Include Python version, OS platform, and any relevant traceback errors. Requesting Features - Outline the proposed feature, the problem it solves, and why it's useful to the broader ecosystem. - Discuss potential alternatives or existing workarounds if applicable.

### Code Examples
```python
git checkout -b feature/your-feature-name

```

```python
git checkout -b bugfix/your-bugfix-name

```

```python
python -m venv env
source env/bin/activate  # On Windows use `env\Scripts\activate`

```



---

## Framework Docs: RELEASE_NOTES.md
**URL**: `https://tubox.cloud/docs/framework/RELEASE_NOTES`

Aquilia v1.3.0 Release date: 2026-07-11 Release Name: "Ironclad Anchor" Summary Aquilia v1.3.0 is a stable release introducing the fluent Controller Attributes builder, renaming the Blueprint validation system to Contracts, and implementing native PyConfig & DotEnv configuration resolution. It also features transaction fixes (`atomic()`), ORM reverse relations updates (`RelatedManager`), and a comprehensive authentication & session forensic audit resolving several security issues and bugs. Changes Added - **Attributes Builder**: Introduced the `Attributes()` fluent builder for declarative controller-level configuration (prefixes, pipelines, tags, instantiation modes, timeouts, exception filters, throttles, etc.) with slot optimizations and definition-time validation. - **Native PyConfig & DotEnv Resolution**: Direct support for `Env` and `Secret` wrappers in integrations and provider builders. - **Field & Ellipsis Improvements**: Enhanced `Field()` to support positional defaults and `...` ellipsis for required fields. - **Effect Registry & Diagnostics**: Replaced generic exception with `EffectNotAcquiredFault` featuring rich diagnostic metadata, and added `_DeferredEffectRegistry` to resolve ASGI startup order dependency issues. - **Atomic Transactions Enhancements**: `@atomic` as a decorator, read-only transaction support (`atomic(readonly=True)`), and Prisma-style interactive timeouts (`atomic(timeout=...)`). - **ORM Reverse Relations & Sentinels**: Lazy `RelatedManager` chaining support (`Model.related_manager()`), `RelatedNotLoaded` sentinel to prevent wrong-type footguns, and cached reverse-accessor resolution. Changed - **Contracts System Rename**: Renamed the entire validation and mapping subsystem from `Blueprint` to `Contract` across all modules, test suites, and documentation. - **Descriptor-based FKs**: Converted `ForeignKey` and `OneToOneField` to generic descriptors for improved IDE autocomplete and static type safety. Fixed - **Authentication & Session Forensic Audit**: - Validated API key non-active statuses (suspended/expired). - Resolved `CredentialStore` protocol/implementation mismatches. - Fixed `RequireSessionAuthGuard`, `RequirePolicyGuard`, and `RequirePermissionGuard` bugs. - Implemented real RBAC checks in template `can()` helper. - Omitted symmetric HMAC keys from JWKS-style `KeyDescriptor.to_dict()` serialization. - Prevented loss of `roles` and `tenant_id` claims during refresh token rotation. - Implemented state context propagation in `set_identity()`. - Added session rotation commit concurrency safety checks. - Enforced client secret validation in OAuth2 confidential client flow and re-checked PKCE in code grant. - Ensured secure locking in `MemoryStore` and `FileStore`. - **Security & Validation Errors**: - Confined local storage paths in `LocalStorage.listdir()` using normalization and root confinement. - Prevented silent bypass of class-level pipelines on `@exempt` routes. - Resolved unhandled exceptions by mapping all framework errors to structured `Fault` sub-classes. - **Database & Transactions**: - Replaced SQL text driving in `Atomic` with connection-bound `begin`/`commit`/`rollback` calls. - Enabled isolation level routing for Postgres and MySQL adapters.


---

## Framework Docs: docs/examples.md
**URL**: `https://tubox.cloud/docs/framework/docs-examples`

Examples Index The repository contains checked example applications under `examples/`: | Example | Purpose | | --- | --- | | `examples/crud_app` | CRUD workspace with database, module manifest, controllers, contracts, models, and service tests. | | `examples/rest_api_contract` | REST API using contracts for request/response contracts. | | `examples/auth_app` | Auth-oriented app with account module and tests. | | `examples/background_jobs` | Background task module and task service tests. | | `examples/websocket_app` | WebSocket chat/presence module with socket controller tests. | | `examples/multi_module_native_app` | Multi-module workspace using accounts, orders, notifications, operations, realtime, templates, and locales. | How To Run Examples Each example is a workspace-shaped application with its own `workspace.py` and `runtime.py`. From an example directory, the source-backed operational flow is: Tests live under each example's `tests/` directory and can be run with `pytest` or through the framework command: Workspace Pattern The CRUD example wires runtime, database, one module, DI, routing, fault handling, and security: The auth starter adds sessions and rate limiting: Manifest Pattern HTTP Controller Pattern The CRUD example controller uses route decorators, request JSON, query parameters, contract validation, and structured `Response` objects: Contract Validation Pattern Service And Fault Pattern The checked service layer raises framework faults that the fault middleware can map into responses: WebSocket Pattern The WebSocket example uses socket decorators, room membership, payload schemas, and acknowledgement events: Background Task Pattern The background jobs example uses `@task`, priority, retry, timeout, and schedule helpers: Module-specific examples are in `docs/modules/<module>/examples.md`.

### Code Examples
```python
aq validate
aq inspect modules
aq inspect routes
aq run

```

```python
aq test

```

```python
from aquilia import Integration, Module, Workspace

workspace = (
    Workspace("project-tracker", version="1.0.0", description="CRUD starter application")
    .runtime(mode="dev", port=8010, reload=True)
    .database(url="sqlite:///runtime/projects.db", auto_create=True, auto_migrate=False)
    .module(Module("projects", version="1.0.0").route_prefix("/projects").tags("crud", "projects"))
    .integrate(Integration.di(auto_wire=True, manifest_validation=True))
    .integrate(Integration.routing(strict_matching=True))
    .integrate(Integration.fault_handling(default_strategy="propagate"))
    .security(cors_enabled=True, helmet_enabled=True)
)

```



---

## Framework Docs: docs/architecture.md
**URL**: `https://tubox.cloud/docs/framework/docs-architecture`

Aquilia Architecture Aquilia is a manifest-first, async-native Python framework. The implementation splits responsibilities across workspace configuration, module manifests, registry compilation, DI setup, controller routing, middleware, ASGI adaptation, and optional subsystems. Runtime Path 1. `workspace.py` declares a `Workspace` with `Module` pointers and `Integration` objects. 2. Each module exposes `modules/<name>/manifest.py` with an `AppManifest` that lists controllers, services, models, socket controllers, middleware, tasks, faults, templates, and metadata. 3. `AquiliaRuntime.configure()` inserts the workspace root into `sys.path`, sets `AQUILIA_ENV` and `AQUILIA_WORKSPACE`, configures logging, and loads config through `ConfigLoader`. 4. `AquiliaRuntime.discover()` extracts workspace/module names, imports module manifests, performs dynamic module discovery, rebuilds the apps namespace, and loads workspace module configuration. 5. `AquiliaRuntime.bootstrap()` constructs `AquiliaServer` with manifests, config, registry mode, and workspace module metadata. 6. `AquiliaServer` builds the Aquilary registry, runtime registry, DI containers, lifecycle coordinator, middleware stack, socket runtime, controller compiler/router/engine, and optional subsystem services. 7. `ASGIAdapter` receives HTTP, WebSocket, and lifespan scopes. 8. HTTP requests are matched by `ControllerRouter`, wrapped by middleware, executed by `ControllerEngine`, and serialized by `Response`. 9. Lifespan startup loads controllers, admin routes, OpenAPI docs, models, lifecycle hooks, effects, cache, storage, mail, tasks, health state, and optional subsystems. Workspace Versus Module Manifest `Workspace` is orchestration: runtime mode, modules, integrations, sessions, security, telemetry, database, MLOps, and env config. `Module` in `workspace.py` is a pointer with route prefix, dependencies, tags, lifecycle, and optional module database override. `AppManifest` is module internals: controllers, services, socket controllers, models, serializers, guards, pipes, interceptors, middleware, sessions, templates, fault handlers, background tasks, features, imports/exports, and discovery settings. HTTP Request Flow 1. `ASGIAdapter.handle_http()` builds the middleware chain once and caches it. 2. The built-in `/_health` endpoint is served before the normal middleware path and only supports GET/HEAD. 3. `Request` wraps the ASGI scope and receive callable. 4. API version inputs are pre-resolved for URL-path matching when versioning is active. 5. `ControllerRouter.match_sync()` selects a route; HEAD can fall back to GET and strip the response body. 6. The adapter creates a request-scoped DI container and pooled controller `RequestCtx`. 7. Middleware descriptors execute in scope/priority order. 8. The final handler calls `ControllerEngine.execute()` with the compiled route, request, path params, and request container. 9. Fault middleware and exception handling convert faults/exceptions to structured JSON or HTML error pages. 10. `Response.send_asgi()` emits ASGI response events. Built-In Runtime Behavior - `/_health` returns engine metrics and subsystem health, with no-store and security headers. - OpenAPI routes are registered at `/openapi.json`, `/docs`, and `/redoc` when docs are enabled. - Admin routes are injected into the controller router when `Integration.admin(...)` is configured. - Static `assets/` can be auto-mounted under `/static` for admin assets when needed. - Dev/test/local modes can force session cookies to insecure mode so browser sessions work on plain HTTP. - Optional subsystem startup failures for mail, cache, tasks, storage, and effects are logged as non-fatal where the implementation catches them. Module Documentation Use [module-index.md](module-index.md) for every module and [runtime-lifecycle.md](runtime-lifecycle.md) for phase-by-phase details.


---

## Framework Docs: docs/module-index.md
**URL**: `https://tubox.cloud/docs/framework/docs-module-index`

Aquilia Module Index Every top-level package under `aquilia/` has a module documentation directory. Root framework files are grouped under `core`. | Module | Role | Files | Lines | Classes | Functions | Constants | Docs | | --- | --- | ---: | ---: | ---: | ---: | ---: | --- | | `core` | Root framework runtime files: ASGI adapter, server, runtime bootstrap, config, pyconfig, request/response, middleware, lifecycle, signing, effects, dotenv, uploads, and data structures. | 22 | 27322 | 132 | 46 | 63 | [README](modules/core/README.md) | | `admin` | Built-in administration interface, audit log, permissions, dashboards, model CRUD, operational pages, and admin security. | 21 | 26075 | 92 | 53 | 22 | [README](modules/admin/README.md) | | `aquilary` | Manifest registry, validation, dependency graph, route table compilation metadata, fingerprinting, and runtime registry construction. | 10 | 4676 | 29 | 9 | 1 | [README](modules/aquilary/README.md) | | `artifacts` | Typed artifact envelopes, artifact kinds, integrity metadata, readers, builders, and memory/filesystem stores. | 6 | 1859 | 19 | 2 | 2 | [README](modules/artifacts/README.md) | | `auth` | Authentication, authorization, identity stores, token management, guards, clearance rules, MFA, OAuth, and session integration. | 24 | 12774 | 164 | 61 | 19 | [README](modules/auth/README.md) | | `contracts` | Model-to-world contracts for request validation, response rendering, schema generation, facets, projections, and lenses. | 9 | 4728 | 41 | 10 | 15 | [README](modules/contracts/README.md) | | `cache` | Async cache abstraction with memory, Redis, composite, null backends, serializers, decorators, DI providers, and HTTP caching middleware. | 14 | 3813 | 27 | 10 | 5 | [README](modules/cache/README.md) | | `cli` | The `aq` command line interface, workspace/module generators, deployment generators, diagnostics, validation, inspection, and subsystem commands. | 42 | 23184 | 25 | 216 | 54 | [README](modules/cli/README.md) | | `controller` | Controller base class, route decorators, compiler, router, execution engine, renderers, filters, pagination, and OpenAPI generation. | 12 | 7813 | 48 | 10 | 21 | [README](modules/controller/README.md) | | `db` | Async database engine facade, typed database configs, adapters for SQLite/Postgres/MySQL/Oracle, and schema introspection helpers. | 9 | 3266 | 15 | 4 | 16 | [README](modules/db/README.md) | | `debug` | Development-mode welcome, HTTP error, version error, and exception pages. | 2 | 1300 | 1 | 4 | 6 | [README](modules/debug/README.md) | | `di` | Scoped dependency injection container, providers, request DAG, decorators, lifecycle disposal, diagnostics, scopes, and testing utilities. | 14 | 4800 | 44 | 16 | 8 | [README](modules/di/README.md) | | `discovery` | AST-based component discovery and manifest synchronization support. | 2 | 747 | 9 | 0 | 1 | [README](modules/discovery/README.md) | | `faults` | Structured fault taxonomy, domains, handlers, middleware, response mapping, and subsystem patch integrations. | 12 | 4801 | 127 | 23 | 4 | [README](modules/faults/README.md) | | `filesystem` | Native async filesystem API, file handles, directory operations, streaming, locks, temporary files, path security, metrics, and service facade. | 14 | 4317 | 25 | 22 | 20 | [README](modules/filesystem/README.md) | | `http` | Native async HTTP client, request/response builders, sessions, retry policies, auth interceptors, cookies, middleware, streaming, and transport. | 17 | 8549 | 100 | 23 | 12 | [README](modules/http/README.md) | | `i18n` | Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. | 11 | 4190 | 28 | 26 | 12 | [README](modules/i18n/README.md) | | `inspector` | Dev-mode request inspector: per-request execution tracing, swimlane spans, DI/DB/HTTP/fault bridges, ring-buffer collector, SSE live stream, replay/export, redaction, and admin panel UI. | 14 | 1016 | 18 | 47 | 3 | — | | `integrations` | Typed workspace integration configuration objects consumed by `Workspace.integrate(...)` and server setup. | 21 | 2978 | 42 | 0 | 4 | [README](modules/integrations/README.md) | | `mail` | Async mail subsystem with message classes, config contracts, providers, DI registration, templates, faults, and convenience send APIs. | 14 | 4599 | 41 | 9 | 14 | [README](modules/mail/README.md) | | `middleware_ext` | Extended production middleware for security, CORS/CSP/CSRF/HSTS, static files, rate limits, sessions, request scopes, effects, and logging. | 8 | 3274 | 22 | 7 | 7 | [README](modules/middleware_ext/README.md) | | `mlops` | Model operations platform: modelpacks, serving, registries, runtimes, orchestration, observability, rollout, optimization, plugins, scheduler, and security. | 76 | 15885 | 212 | 30 | 24 | [README](modules/mlops/README.md) | | `models` | Pure-Python async ORM, fields, query builder, managers, SQL builders, migrations, schema snapsh


---

## Framework Docs: docs/faults-system.md
**URL**: `https://tubox.cloud/docs/framework/docs-faults-system`

Aquilia Fault System The Fault System provides structured, type-safe error management for Aquilia applications. Instead of relying on bare, unformatted Python exceptions, Aquilia treats errors as first-class structured values called **Faults**. Inheriting from Python's base `Exception` class, every `Fault` is enriched with stable identifiers, severity ratings, classification domains, and recovery strategies. --- Core Concepts & Classes The system relies on four core elements: 1. **Fault Base Class (`Fault`)**: Subclasses `Exception` but carries rich metadata. Unlike normal exceptions, it contains stable error codes (e.g. `USER_NOT_FOUND`), human-readable messages, severity levels, domains, and public exposure controls. 2. **Fault Domain (`FaultDomain`)**: Groups errors taxonomically by subsystem (e.g. `CONFIG`, `ROUTING`, `DI`, `MODEL`, `CACHE`, `SECURITY`, `HTTP`). Domains establish default severity and retryability behaviors. 3. **Fault Context (`FaultContext`)**: Wraps a `Fault` with runtime variables captured during error propagation (e.g. `trace_id`, `request_id`, `app`, `route`, and the original stack trace). 4. **Fault Result (`FaultResult`)**: Determines the resolution state of a fault after traversing a handler: * `Resolved(response)`: The error was handled; execution stops and returns the response. * `Transformed(fault)`: The error was converted to another fault type and continues propagation. * `Escalate`: The handler declined to process this fault; it bubbles up to the next handler. --- Fault Severity & Recovery Strategies Severity Levels (`Severity`) * `INFO`: Informational, logged but requires no recovery action. * `WARN`: Warning, indicators of potential issues that should be reviewed. * `ERROR`: Error, immediate attention needed (default for custom/scoped errors). * `FATAL` (or `CRITICAL`): Unrecoverable error. Aborts processing immediately. Recovery Strategies (`RecoveryStrategy`) * `PROPAGATE`: Bubble up to the next scope handler. * `RETRY`: Retry the failed operation (with optional backoff). * `FALLBACK`: Return a pre-configured fallback value. * `MASK`: Suppress the error from the response (log it only). * `CIRCUIT_BREAK`: Trip the circuit breaker for downstream requests. --- Fault Lifecycle Execution Flow For every raised exception or structured fault, the framework coordinates a 6-step lifecycle: --- Workspace Integration: Fault Middleware Register the `FaultMiddleware` in your `workspace.py` to catch uncaught exceptions, process them, and transform them to clean API responses. --- Practical Code Examples 1. Declaring and Raising Structured Faults Arbitrary keyword arguments passed to the constructor are automatically merged into the `metadata` dictionary: 2. Preserving Causality: Transform Chain (`>>`) Faults override the right-shift operator (`>>`). This converts a lower-level technical exception (e.g. database connection timeout) to a higher-level public API fault while keeping track of the causal chain under the `_cause` and `_transform_chain` metadata keys: 3. Writing Scoped Fault Handlers Define custom error handlers and register them with the engine to resolve specific faults:

### Code Examples
```python
[Raised Exception / Fault]
           │
           ▼
     [1. Origin]         ◄─── Exception caught & transformed to Fault
           │
           ▼
   [2. Annotation]       ◄─── Wrapped in FaultContext (trace_id & stack trace)
           │
           ▼
    [3. Emission]        ◄─── Logged & dispatched to event_listeners
           │
           ▼
   [4. Propagation]      ◄─── Routed through: Route ➔ Controller ➔ App ➔ Global
           │
           ▼
    [5. Resolution]      ◄─── Resolved, Transformed, or Escalated
           │
           ▼
     [6. Response]       ◄─── FaultMiddleware serializes to clean JSON HTTP response

```

```python
from aquilia.workspace import Workspace
from aquilia.middleware import MiddlewareChain
from aquilia.faults.engine import get_default_engine

app = (
    Workspace.new("my-project")
    .middleware(
        MiddlewareChain.chain()
        .defaults()
        # Binds the global FaultEngine bridge
        .use("aquilia.faults.engine.FaultMiddleware", engine=get_default_engine())
    )
)

```

```python
from aquilia.faults import Fault, FaultDomain, Severity

raise Fault(
    code="OUT_OF_STOCK",
    message="Requested inventory quantity exceeds active stock",
    domain=FaultDomain.MODEL,
    severity=Severity.ERROR,
    public=True,
    product_id="prod_9982",
    requested_qty=5
)

```



---

## Framework Docs: docs/developer-guide.md
**URL**: `https://tubox.cloud/docs/framework/docs-developer-guide`

Developer Guide This guide documents the implementation patterns visible in the source tree. For exhaustive symbol signatures, use each module's `api-reference.md`; this page focuses on how those pieces fit together when extending Aquilia. Build A Module 1. Add a module with `aq add module <name>`. 2. Put transport code in `modules/<name>/controllers.py`. 3. Put business logic in `modules/<name>/services.py`. 4. Declare controllers/services/models/socket controllers/tasks in `modules/<name>/manifest.py`. 5. Point the workspace at the module with `Module("name").route_prefix("/name")`. The checked CRUD example uses this shape: Its module manifest declares concrete dotted references: Extend With Services Declare services in `AppManifest.services`. The runtime registry registers services into app DI containers before controller factories are created. Constructor injection is preferred because `ControllerFactory` and DI providers can resolve annotated dependencies. Service classes are ordinary Python objects. The runtime sees them through manifest paths and DI registration. Tests can instantiate them directly, as the checked examples do, when behavior does not require ASGI or container state. Add Controllers Controllers extend `Controller` and use route decorators such as `GET`, `POST`, `PATCH`, and `DELETE`. Handler methods receive `RequestCtx`; they can read JSON with `await ctx.json()`, access query parameters through `ctx.query_param(...)`, and return `Response` instances. Add Contracts Contracts are annotation-driven request/response contracts. The repository examples use `Contract` classes with typed attributes, `Spec` options, and `seal_<field>` methods that mutate or reject incoming data. Add Middleware Use `Integration.middleware(...)` or manifest middleware declarations. Internal framework middleware is always registered: fault handling and request-scope cleanup. Security/static/rate-limit/session/auth/template/i18n/cache middleware are added by server setup when configured. Add CLI Commands Mounted commands live in `aquilia/cli/__main__.py` and implementation helpers live under `aquilia/cli/commands/`. Subsystem-local CLI helpers exist in some modules, but only commands mounted in the root Click tree appear in `aq --help` and this documentation. Add Providers Or Backends Follow existing backend/provider contracts: cache backends implement `CacheBackend`, storage backends extend `StorageBackend`, mail providers implement `IMailProvider`, socket scaling backends implement `Adapter`, database adapters extend `DatabaseAdapter`, and MLOps runtimes extend runtime base classes. When adding a backend, keep the implementation behind the subsystem contract and wire it through the existing config or provider registry. Avoid calling optional third-party packages at import time unless that subsystem already requires them; several modules load optional dependencies only when a configured backend needs them. Add WebSocket Controllers Socket controllers use decorators from `aquilia.sockets` and are declared in the module manifest. The checked WebSocket example shows room membership, event schemas, and ack events: Add Background Tasks The tasks subsystem exposes `@task` and schedule helpers. Tasks are declared by dotted path in the module manifest and are started by server startup when task integration is configured. Testing Use `aquilia.testing` for `TestClient`, `TestServer`, base test cases, config overrides, DI mocks, effect mocks, mail outbox helpers, and request factories. The CLI command `aq test` sets `AQUILIA_ENV=test` and delegates to pytest with Aquilia-aware defaults. Change Checklist 1. Update `workspace.py` when the workspace should know about a module or integration. 2. Update `modules/<name>/manifest.py` when runtime discovery should load a controller, service, model, socket controller, middleware, task, template, or fault handler. 3. Run `aq validate` after manifest edits. 4. Run `aq inspect routes`, `aq inspect modules`, or `aq inspect config` when debugging runtime wiring. 5. Add tests under `tests/` or the example app's test directory for behavior that can be exercised without a running server.

### Code Examples
```python
from aquilia import Integration, Module, Workspace

workspace = (
    Workspace("project-tracker", version="1.0.0")
    .runtime(mode="dev", port=8010, reload=True)
    .database(url="sqlite:///runtime/projects.db", auto_create=True, auto_migrate=False)
    .module(Module("projects", version="1.0.0").route_prefix("/projects").tags("crud", "projects"))
    .integrate(Integration.di(auto_wire=True, manifest_validation=True))
    .integrate(Integration.routing(strict_matching=True))
    .integrate(Integration.fault_handling(default_strategy="propagate"))
    .security(cors_enabled=True, helmet_enabled=True)
)

```

```python
from aquilia import AppManifest
from aquilia.manifest import FaultHandlingConfig

manifest = AppManifest(
    name="projects",
    version="1.0.0",
    controllers=["modules.projects.controllers:ProjectsController"],
    services=["modules.projects.services:ProjectsService"],
    models=["modules.projects.models:Project"],
    base_path="modules.projects",
    tags=["projects"],
    faults=FaultHandlingConfig(default_domain="PROJECTS", strategy="propagate"),
)

```

```python
from aquilia import Controller, GET, POST, RequestCtx, Response

class ProjectsController(Controller):
    prefix = "/"

    @GET("/")
    async def list_projects(self, ctx: RequestCtx):
        return Response.json({"items": []})

    @POST("/", status_code=201)
    async def create_project(self, ctx: RequestCtx):
        payload = await ctx.json()
        return Response.json(payload, status=201)

```



---

## Framework Docs: docs/operations-security.md
**URL**: `https://tubox.cloud/docs/framework/docs-operations-security`

Operations And Security Health And Metrics `ASGIAdapter` serves `GET /_health` and `HEAD /_health` before normal route dispatch. The response includes engine metrics and subsystem health when `HealthRegistry` is available. Non-GET/HEAD methods receive 405. The health route is intentionally handled before controller routing and middleware dispatch. Use it for process and load-balancer readiness checks, but do not treat it as a substitute for subsystem-specific checks such as database migrations, mail delivery, provider credentials, or registry reachability. Secrets Set `AQ_SECRET_KEY` or `SECRET_KEY`, or configure `AquilaConfig.Signing.secret`. Non-dev auth token secrets must not be insecure defaults. Relevant source-backed secret surfaces: | Surface | Source-backed behavior | | --- | --- | | Signing | `AquiliaServer._bootstrap_signing()` reads configured signing secret plus `AQ_SECRET_KEY` and `SECRET_KEY` fallbacks. | | Auth tokens | Auth configuration validates token secrets and rejects insecure non-dev defaults. | | Provider credentials | Provider commands and credential stores live under `aquilia.providers`; Render credential storage uses the encrypted credential helpers documented in that module. | | Dotenv | `DotEnvLoader.ensure_loaded()` participates in config loading before `AQ_` overlays and explicit overrides. | Admin Admin requires sessions or auth. `aq admin check` validates prerequisites. Admin route registration is controlled by `Integration.admin(...)` and per-module enable flags. Operational admin commands are mounted under `aq admin`: `check`, `setup`, `status`, `createsuperuser`, `createstaff`, `listusers`, `changepassword`, and `audit`. See [Admin CLI Reference](modules/admin/cli-reference.md) for arguments, options, and defaults extracted from Click. Middleware Priorities Source comments in `AquiliaServer._setup_security_middleware()` assign security/static middleware priorities: proxy fix 3, HTTPS redirect 4, static files 6, security headers 7, HSTS 8, CSP 9, CORS 11, rate limit 12, CSRF 20. Fault middleware is priority 2 and request-scope middleware priority 5. Middleware ordering matters because fault handling and request-scope cleanup are framework safety rails. Security-related middleware is added by server setup when configured by `Workspace.security(...)` and integration objects. Manifest and workspace custom middleware should be checked with `aq inspect config` and runtime startup logs when behavior depends on order. Production Entrypoint Use `aquilia.entrypoint:app` with `AQUILIA_WORKSPACE` and `AQUILIA_ENV=prod`. If the workspace is missing, the entrypoint provides a 503 stub response instead of silently failing. Production startup paths: `aq serve` is the mounted production CLI command. It accepts worker, bind, gunicorn, timeout, and graceful-timeout options; see [CLI Reference](cli-reference.md). Deployment Checks 1. Run `aq validate` before packaging or deployment. 2. Run `aq doctor` in the target environment where provider credentials and workspace files are present. 3. Run `aq inspect config` and verify resolved values do not contain development defaults. 4. Run database migration commands for configured model stores before serving traffic. 5. Verify `GET /_health` after startup. Error Handling In Production Structured faults from `aquilia.faults` are converted by fault middleware. Unexpected exceptions are handled by the ASGI/server exception paths and, depending on mode, can render development pages or production-safe responses. Keep `AQUILIA_ENV=prod` for production entrypoints so development behavior is not enabled accidentally.

### Code Examples
```python
AQUILIA_WORKSPACE=/srv/app AQUILIA_ENV=prod uvicorn aquilia.entrypoint:app --host 0.0.0.0 --port 8000

```



---

## Framework Docs: docs/runtime-lifecycle.md
**URL**: `https://tubox.cloud/docs/framework/docs-runtime-lifecycle`

Runtime Lifecycle This page traces the concrete boot path implemented by `aquilia/runtime.py`, `aquilia/server.py`, and `aquilia/asgi.py`. It complements the generated module API pages by describing the order in which the runtime wires the framework together. AquiliaRuntime Phases `AquiliaRuntime` moves through `CREATED`, `CONFIGURING`, `DISCOVERING`, `BOOTSTRAPPING`, `READY`, `RUNNING`, `SHUTTING_DOWN`, `STOPPED`, and `FAILED`. - `configure()` inserts the workspace root into `sys.path`, sets environment defaults, configures logging, verifies `workspace.py`, and loads config. - `discover()` parses workspace content, imports declared manifests, dynamically discovers module directories with `manifest.py`, rebuilds app config namespaces, and loads workspace module metadata. - `bootstrap()` builds `AquiliaServer` with the correct `RegistryMode`. - `.app` and `.server` are only available in `READY` or `RUNNING` phases. Configuration Phase `AquiliaRuntime.configure()` is the first phase that touches the user workspace. The runtime resolves the workspace root, adds it to `sys.path` when needed, sets `AQUILIA_WORKSPACE`, sets an environment mode through `AQUILIA_ENV`, configures logging, requires `workspace.py`, and loads configuration through `ConfigLoader`. A missing workspace file fails during this phase instead of allowing later server construction to proceed with partial state. `ConfigLoader.load()` merges workspace structure, optional legacy config, explicit dotenv input, native dotenv loading, `AQ_` environment overlays, and explicit overrides. The runtime keeps the loaded config and workspace metadata for later discovery and server construction. Discovery Phase `AquiliaRuntime.discover()` imports the workspace, extracts declared modules, imports each declared `modules/<name>/manifest.py`, and discovers module directories that expose a manifest. It also rebuilds namespace configuration for discovered apps and captures workspace module metadata used by `AquiliaServer`. Discovery is intentionally source-driven: manifests contain dotted references to controllers, services, models, socket controllers, tasks, middleware, templates, and fault handlers. Invalid dotted paths are reported by validation and startup paths rather than silently ignored. Server Startup `AquiliaServer.startup()` is idempotent and guarded by an async lock. It performs runtime auto-discovery, loads controllers, wires admin routes, compiles routes, runs lifecycle hooks, registers models, validates model registry completeness, starts mail/tasks/cache/storage/effects where configured, and registers health statuses. Startup also builds or initializes the subsystems used by request execution: | Area | Runtime behavior | | --- | --- | | Registry | Builds the Aquilary registry/runtime registry from manifests and workspace module metadata. | | Dependency injection | Creates app containers, registers services/providers, and creates request-scoped containers per request. | | Routing | Loads controller classes, compiles decorators into routes, registers admin/docs routes where enabled, and stores route metadata for inspection. | | Middleware | Registers built-in fault and request-scope middleware, then adds configured security, sessions, auth, templates, i18n, cache, static, rate-limit, and custom middleware. | | WebSockets | Initializes socket controller runtime and adapter when socket controllers are declared. | | Models and database | Registers model classes, validates registry completeness, and connects configured databases where required. | | Background services | Starts mail, cache, storage, task, effect, and health integrations where configured. | Request Lifecycle `ASGIAdapter.handle_http()` builds/caches middleware, handles `/_health`, wraps ASGI in `Request`, pre-resolves versioning, matches a route, allocates request DI scope and `RequestCtx`, executes middleware, calls the controller engine, records metrics, releases the context, and sends the response. Detailed HTTP flow: 1. `ASGIAdapter.__call__()` dispatches by scope type: `http`, `websocket`, or `lifespan`. 2. `handle_http()` serves `GET /_health` and `HEAD /_health` before normal routing. 3. `Request` wraps the ASGI scope and receive callable. 4. The adapter asks the router for a compiled route; `HEAD` can fall back to `GET`. 5. A request container and pooled `RequestCtx` are allocated. 6. Middleware descriptors execute in configured order. 7. The final handler calls `ControllerEngine.execute()`. 8. Fault handling converts structured faults and unexpected exceptions into framework responses. 9. The response is emitted with `Response.send_asgi()`. 10. Metrics are recorded and request scope resources are released. WebSocket Lifecycle `ASGIAdapter.handle_websocket()` delegates WebSocket scopes to the server socket runtime. Socket controllers are declared through module manifests and decorators from `aquilia.sockets`; the socket runtime owns connection state, room membership, event dispatc


---

## Framework Docs: docs/effects-system.md
**URL**: `https://tubox.cloud/docs/framework/docs-effects-system`

Aquilia Effect System The Effect System provides structured, type-safe resource injection for Aquilia applications. Inspired by functional effect systems (specifically Effect-TS), it separates *what* resource a handler requires from *how* that resource is constructed, accessed, and cleaned up. This pattern decouples handlers from infrastructure, ensuring clean boundaries, testability, and robust resource safety. An "Effect" acts as a typed token representing a dependency (e.g. database transaction, cache namespace, message queue, HTTP client, or blob storage bucket). Instead of instantiating clients directly or pulling them from global state, handlers declare their required effects using the `@requires` decorator. The Aquilia runtime automatically manages the lifecycle (acquisition, verification, and releasing/committing) of these resources around handler invocation. --- Core Architecture & Components The system is built on four core layers: 1. **Effect Token (`Effect`)**: A symbolic description of a capability, parameterized by a name and an optional mode (e.g. `DBTx["read"]` vs. `DBTx["write"]`). 2. **EffectProvider (`EffectProvider`)**: The abstract base class representing the implementation backend for an effect. It manages the lifecycle of actual resources through five hook methods: * `initialize()`: One-time setup during application bootstrap. * `acquire(mode)`: Setup executed per-request or per-scope to create a handle. * `release(resource, success)`: Teardown executed per-request, handling commits, rollbacks, or connection cleanup. * `finalize()`: One-time shutdown cleanup when the server stops. * `health_check()`: Aggregates capability health statistics. 3. **EffectRegistry (`EffectRegistry`)**: A centralized registry storing mappings of effect names to providers. It integrates with the Dependency Injection (DI) system as an application-scoped singleton. 4. **Resource Handles**: Lightweight, specialized classes that act as the interface through which handlers interact with the underlying capability. For example, `DBTxHandle`, `CacheServiceHandle`, `QueueHandle`, `HTTPHandle`, and `StorageHandle`. --- Request Lifecycle Execution Flow The framework executes a clean three-step lifecycle for every request requesting effects: --- Workspace Integration To enable the Effect system in your workspace, register `FlowContextMiddleware` and `EffectMiddleware` in your `workspace.py` file. > [!IMPORTANT] > **Middleware Execution Order:** > `FlowContextMiddleware` must come **before** `EffectMiddleware` in the middleware chain. This ensures that the `FlowContext` is initialized before the Effect Middleware attempts to propagate acquired resource handles into it. Code Example: Workspace Setup You can also explicitly register providers during integration setups: --- Declaring Required Effects Route handlers and flow pipeline nodes declare their capability requirements using the `@requires` decorator. > [!WARNING] > **Decorator Order is Critical:** > `@requires` must be applied **closer to the function body** than the HTTP route decorator (e.g. `@POST` or `@GET`). Python applies decorators from the bottom up, so `@requires` must attach metadata to the raw function first. --- Built-in Effects Aquilia packages five core capabilities: 1. Database Transaction (`DBTx`) Leases database connections and manages atomic scopes. * **Modes**: * `DBTx["read"]`: Read-only connection, optimized for SELECT queries, can target read replicas. * `DBTx["write"]`: Starts an active transaction block. Automatically commits on successful request return, or executes a rollback on handler exception. * **Handle Interface (`DBTxHandle`)**: * `await execute(sql, params)` * `await fetch_all(sql, params)` * `await fetch_one(sql, params)` * `await fetch_val(sql, params)` * `await execute_many(sql, params_list)` 2. Cache Effect (`CacheEffect`) Provides key-value caching scoped by namespace to prevent key overlap. * **Handle Interface (`CacheServiceHandle` / `CacheHandle`)**: * `await get(key)`: Returns deserialized value or `None` on cache miss. * `await set(key, value, ttl=None)`: Caches value. Optional TTL is in seconds. * `await delete(key)`: Deletes key, returns status. 3. Queue Effect (`QueueEffect`) Publishes events to message brokers or enqueues asynchronous background tasks. * **Modes**: Parameterized by topic name (e.g. `QueueEffect("telemetry")`). * **Handle Interface**: * **Broker Publish (`QueueHandle`)**: * `await publish(payload, headers=None)`: Sends payload with metadata. * `await publish_batch(payloads)`: Sends list of payloads. * **Task Worker (`TaskQueueHandle`)**: * `await enqueue(func, *args, **kwargs)`: Submits a background task to the worker runner, returning the Job ID. 4. HTTP client (`HTTPEffect`) Injects pre-configured HTTP clients with built-in connection reuse, timeout controls, and headers. * **Handle Interface (`HTTPHandle`)**: * `await get(url, **kwargs)` * `await post(url, json=None, **kwargs)` * `await put(url, jso

### Code Examples
```python
[HTTP Request]
       │
       ▼
[FlowContextMiddleware]  ◄─── Creates request-scoped FlowContext
       │
       ▼
[EffectMiddleware]      ◄─── 1. Detects @requires tokens on handler
       │                     2. Lazy-resolves providers via proxy
       │                     3. Runs provider.acquire() to lease handle
       │                     4. Injects handle into request state & FlowContext
       ▼
[Controller Handler]    ◄─── Interacts with ctx.get_effect("DBTx")
       │
       ▼
[EffectMiddleware]      ◄─── 1. Runs provider.release(resource, success=True/False)
       │                     2. DBTx commits on success, rolls back on exception
       ▼
[HTTP Response]

```

```python
from aquilia.workspace import Workspace
from aquilia.middleware import MiddlewareChain

app = (
    Workspace.new("my-project")
    .middleware(
        MiddlewareChain.chain()
        .defaults()
        # FlowContextMiddleware (priority 14) executes before EffectMiddleware (priority 15)
        .use("aquilia.middleware_ext.FlowContextMiddleware", priority=14)
        .use("aquilia.middleware_ext.EffectMiddleware", priority=15)
    )
)

```

```python
from aquilia.integrations import Integration

Integration.effects(
    providers={
        "DBTx": {
            "class": "aquilia.effects.DBTxProvider",
            "args": {"connection_string": "postgresql://user:pass@localhost:5432/db"}
        },
        "Cache": {
            "class": "aquilia.effects.CacheProvider",
            "args": {"backend": "redis"}
        }
    }
)

```



---

## Framework Docs: docs/README.md
**URL**: `https://tubox.cloud/docs/framework/docs-README`

Aquilia Documentation This documentation is generated from the current `aquilia/` source tree and the live `aq` Click command tree. It documents implemented behavior: source files, public APIs, configuration objects, runtime lifecycle, command arguments/options, extension points, examples, edge cases, and troubleshooting paths. Start Here 1. [Architecture](architecture.md) explains the framework boot path and request flow. 2. [Installation](installation.md) lists requirements, extras, and setup flow from `pyproject.toml`. 3. [Configuration](configuration.md) documents `Workspace`, `Module`, `Integration`, `AquilaConfig`, dotenv, and `AQ_` environment overlays. 4. [CLI Reference](cli-reference.md) is the complete mounted `aq` command reference. 5. [Runtime Lifecycle](runtime-lifecycle.md) traces ASGI startup, request execution, and shutdown. 6. [Developer Guide](developer-guide.md) covers modules, providers, middleware, hooks, services, tests, and extension points. 7. [Examples](examples.md) indexes checked examples under `examples/`. 8. [Coverage Report](documentation-coverage-report.md) records what was audited and rebuilt. Module Map | Module | Role | Files | Classes | Functions | API | CLI | | --- | --- | ---: | ---: | ---: | --- | --- | | [core](modules/core/README.md) | Root framework runtime files: ASGI adapter, server, runtime bootstrap, config, pyconfig, request/response, middleware, lifecycle, signing, effects, dotenv, uploads, and data structures. | 22 | 132 | 46 | [API](modules/core/api-reference.md) | [CLI](modules/core/cli-reference.md) | | [admin](modules/admin/README.md) | Built-in administration interface, audit log, permissions, dashboards, model CRUD, operational pages, and admin security. | 21 | 92 | 53 | [API](modules/admin/api-reference.md) | [CLI](modules/admin/cli-reference.md) | | [aquilary](modules/aquilary/README.md) | Manifest registry, validation, dependency graph, route table compilation metadata, fingerprinting, and runtime registry construction. | 10 | 29 | 9 | [API](modules/aquilary/api-reference.md) | [CLI](modules/aquilary/cli-reference.md) | | [artifacts](modules/artifacts/README.md) | Typed artifact envelopes, artifact kinds, integrity metadata, readers, builders, and memory/filesystem stores. | 6 | 19 | 2 | [API](modules/artifacts/api-reference.md) | [CLI](modules/artifacts/cli-reference.md) | | [auth](modules/auth/README.md) | Authentication, authorization, identity stores, token management, guards, clearance rules, MFA, OAuth, and session integration. | 24 | 164 | 61 | [API](modules/auth/api-reference.md) | [CLI](modules/auth/cli-reference.md) | | [contracts](modules/contracts/README.md) | Model-to-world contracts for request validation, response rendering, schema generation, facets, projections, and lenses. | 9 | 41 | 10 | [API](modules/contracts/api-reference.md) | [CLI](modules/contracts/cli-reference.md) | | [cache](modules/cache/README.md) | Async cache abstraction with memory, Redis, composite, null backends, serializers, decorators, DI providers, and HTTP caching middleware. | 14 | 27 | 10 | [API](modules/cache/api-reference.md) | [CLI](modules/cache/cli-reference.md) | | [cli](modules/cli/README.md) | The `aq` command line interface, workspace/module generators, deployment generators, diagnostics, validation, inspection, and subsystem commands. | 42 | 25 | 216 | [API](modules/cli/api-reference.md) | [CLI](modules/cli/cli-reference.md) | | [controller](modules/controller/README.md) | Controller base class, route decorators, compiler, router, execution engine, renderers, filters, pagination, and OpenAPI generation. | 12 | 48 | 10 | [API](modules/controller/api-reference.md) | [CLI](modules/controller/cli-reference.md) | | [db](modules/db/README.md) | Async database engine facade, typed database configs, adapters for SQLite/Postgres/MySQL/Oracle, and schema introspection helpers. | 9 | 15 | 4 | [API](modules/db/api-reference.md) | [CLI](modules/db/cli-reference.md) | | [debug](modules/debug/README.md) | Development-mode welcome, HTTP error, version error, and exception pages. | 2 | 1 | 4 | [API](modules/debug/api-reference.md) | [CLI](modules/debug/cli-reference.md) | | [di](modules/di/README.md) | Scoped dependency injection container, providers, request DAG, decorators, lifecycle disposal, diagnostics, scopes, and testing utilities. | 14 | 44 | 16 | [API](modules/di/api-reference.md) | [CLI](modules/di/cli-reference.md) | | [discovery](modules/discovery/README.md) | AST-based component discovery and manifest synchronization support. | 2 | 9 | 0 | [API](modules/discovery/api-reference.md) | [CLI](modules/discovery/cli-reference.md) | | [faults](modules/faults/README.md) | Structured fault taxonomy, domains, handlers, middleware, response mapping, and subsystem patch integrations. | 12 | 127 | 23 | [API](modules/faults/api-reference.md) | [CLI](modules/faults/cli-reference.md) | | [filesystem](modules/filesystem/README.md) | Native async filesystem API, file handl


---

## Framework Docs: docs/auth-methods.md
**URL**: `https://tubox.cloud/docs/framework/docs-auth-methods`

Aquilia Auth Methods Reference This document lists practical authentication and authorization methods available in Aquilia, from global configuration down to route-level behavior. 1. Global Auth Integration Enable auth system wiring in workspace configuration so AuthManager and related dependencies are available. Example in workspace.py: Notes: - If auth integration is not enabled, guards like AuthGuard may fail with DI_RESOLUTION_FAILED for AuthManager. - Sessions are typically used alongside auth integration. 2. Core Guard Methods (aquilia.auth.guards) AuthGuard Constructor: Behavior: - optional=False: unauthenticated request raises AUTH_REQUIRED. - optional=True: request continues with identity set to None. - If auth_manager is omitted, it is resolved from DI context/container. Typical controller usage: RoleGuard Constructor: Behavior: - Asserts that the authenticated identity holds the specified roles. - Supports role inheritance when a `PermissionEngine` is resolved or passed. ScopeGuard Constructor: Behavior: - Asserts that the authenticated identity holds the specified OAuth scopes. PolicyGuard Constructor: Behavior: - Enforces a registered custom authorization policy from the `PermissionEngine`. 3. Flow Graph Integration Because all stateless guards in `aquilia.auth.guards` implement the callable protocol (`__call__`), they can be registered directly as nodes inside Aquilia flow pipelines without any adapter classes. 4. Controller-Level vs Route-Level Auth Class-level pipeline (applies to all endpoints in controller) Route-level pipeline (applies only to one endpoint) Route-level override to bypass class-level guard If class-level pipeline is guarded and one route should be public, provide route-level pipeline explicitly. 5. Optional Auth + Redirect Pattern If you want a page to be accessible to anonymous users but still redirect authenticated users: 6. Clearance Methods (aquilia.auth.clearance) Clearance provides declarative access control. AccessLevel Common levels: - PUBLIC - AUTHENTICATED - INTERNAL - CONFIDENTIAL - RESTRICTED grant decorator exempt decorator Use exempt to force public access for specific routes when class-level clearance exists. 7. Middleware-Level Auth In auth integration middleware, require_auth controls global enforcement. - require_auth=True: all requests require auth unless your app explicitly handles exceptions. - require_auth=False: requests may be anonymous; downstream routes/guards decide. 8. Common Method Combinations Public page + protected APIs in one controller Option A: - Use class-level AuthGuard(optional=True). - In each endpoint, branch on ctx.identity. Option B: - No class-level guard. - Add route-level pipeline only on protected endpoints. Strictly protected controller with one public endpoint - Keep class-level guard. - Override specific endpoint with route-level pipeline=[]. 9. Troubleshooting DI_RESOLUTION_FAILED for AuthManager Cause: - Auth integration/provider registration missing. Fix: - Ensure workspace config includes Integration.auth(enabled=True, ...). - Ensure app is restarted after config changes. Unexpected auth requirement on a route Cause: - Class-level pipeline with AuthGuard affects all methods. Fix: - Move guard to route-level only, or override with route-level pipeline=[]. Want browser redirect instead of JSON 401/403 Fix: - Handle inside endpoint with Response.redirect. - Or implement custom middleware/error handling to convert auth faults into redirects for HTML requests. 10. Quick Cheatsheet - Guard all routes in controller: pipeline = [AuthGuard] - Allow anonymous + optional identity: pipeline = [AuthGuard(optional=True)] - Guard one route only: @GET(..., pipeline=[AuthGuard]) - Make one route public while class is guarded: @GET(..., pipeline=[]) - Redirect if unauthenticated: if ctx.identity is None: return Response.redirect("/login") - Use declarative access rules: @grant(...) and @exempt

### Code Examples
```python
.integrate(Integration.auth(
    enabled=True,
    store_type="memory",
))

```

```python
AuthGuard(auth_manager: AuthManager | None = None, optional: bool = False)

```

```python
class UsersController(Controller):
    pipeline = [AuthGuard]

```



---

## Framework Docs: docs/configuration.md
**URL**: `https://tubox.cloud/docs/framework/docs-configuration`

Configuration Reference Aquilia configuration is Python-native. The implementation centers on `Workspace`, `Module`, `Integration`, `AquilaConfig`, dotenv loading, and `ConfigLoader`. Source Files - `aquilia/config_builders.py`: fluent `Workspace`, `Module`, and `Integration` builders. - `aquilia/pyconfig.py`: class-based `AquilaConfig`, `Env`, `Secret`, dotenv policies, and `PyConfigLoader`. - `aquilia/config.py`: `ConfigLoader`, namespace access, environment variable merging, and subsystem config accessors. - `aquilia/integrations/*.py`: typed integration config objects. ConfigLoader Precedence `ConfigLoader.load()` merges in this order: 1. Workspace structure from `workspace.py` or `aquilia.py`. 2. Legacy `config/env.py` if it exists. 3. Explicit `.env` file if `env_file` is passed. 4. Native dotenv auto-load through `DotEnvLoader.ensure_loaded()`. 5. `AQ_` environment variables, with double underscores converted to nested keys. 6. Manual overrides. Environment Variables - `AQUILIA_ENV`: runtime mode used by `AquiliaRuntime` and entrypoint (`dev`, `test`, `prod`, or `production` normalized to `prod`). - `AQUILIA_WORKSPACE`: workspace root for runtime/entrypoint resolution. - `AQ_*`: generic config overlay consumed by `ConfigLoader`; `AQ_AUTH__TOKENS__SECRET_KEY` becomes `auth.tokens.secret_key`. - `AQ_ENV`: legacy/pyconfig environment selector used by `AquilaConfig.for_env()` fallback paths. - `AQ_SECRET_KEY` and `SECRET_KEY`: signing secret fallbacks used by `AquiliaServer._bootstrap_signing()`. YAML Status YAML config is removed. `ConfigLoader._load_yaml_file()` raises `ConfigInvalidFault` and instructs users to migrate to `AquilaConfig` classes in `workspace.py`. Workspace Builder Surface See [Core Configuration](modules/core/configuration.md) and [Integrations Configuration](modules/integrations/configuration.md) for source-extracted builder methods and integration classes.


---

## Framework Docs: docs/cli-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-cli-reference`

Aquilia CLI Reference This is the complete mounted `aq` command tree generated from `aquilia.cli.__main__.cli`. Root Options | Option | Purpose | | --- | --- | | `--version` | Show the version and exit. | | `--verbose, -v` | Verbose output (show debug details, full tracebacks) | | `--quiet, -q` | Minimal output (suppress banners & decorations) | | `--debug` | Enable debug mode (full stack traces on errors) | | `--no-color` | Disable coloured output | Commands `aq init workspace` Create a new Aquilia workspace. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Argument | `name` | `name` | False | `` | | Option | `minimal` | `--minimal` | False | `False` | | Option | `template` | `--template` | False | `not set` | | Option | `yes` | `--yes, -y` | False | `False` | `aq add module` Add a new module to the workspace. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Argument | `name` | `name` | False | `` | | Option | `depends_on` | `--depends-on` | False | `not set` | | Option | `fault_domain` | `--fault-domain` | False | `not set` | | Option | `route_prefix` | `--route-prefix` | False | `not set` | | Option | `with_tests` | `--with-tests` | False | `False` | | Option | `minimal` | `--minimal` | False | `False` | | Option | `no_docker` | `--no-docker` | False | `False` | | Option | `yes` | `--yes, -y` | False | `False` | `aq generate controller` Generate a new controller. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Argument | `name` | `name` | True | `not set` | | Option | `prefix` | `--prefix` | False | `not set` | | Option | `resource` | `--resource` | False | `not set` | | Option | `simple` | `--simple` | False | `False` | | Option | `with_lifecycle` | `--with-lifecycle` | False | `False` | | Option | `test` | `--test` | False | `False` | | Option | `output` | `--output` | False | `not set` | `aq validate` Validate workspace manifests. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `strict` | `--strict` | False | `False` | | Option | `module` | `--module` | False | `not set` | | Option | `as_json` | `--json` | False | `False` | `aq compile` Compile manifests to artifacts. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `watch` | `--watch` | False | `False` | | Option | `output` | `--output` | False | `not set` | `aq run` Start development server. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `mode` | `--mode` | False | `dev` | | Option | `port` | `--port` | False | `` | | Option | `host` | `--host` | False | `` | | Option | `reload` | `--reload, --no-reload` | False | `` | | Option | `skip_checks` | `--skip-checks` | False | `False` | `aq serve` Start production server. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `workers` | `--workers` | False | `` | | Option | `bind` | `--bind` | False | `` | | Option | `use_gunicorn` | `--use-gunicorn` | False | `False` | | Option | `timeout` | `--timeout` | False | `120` | | Option | `graceful_timeout` | `--graceful-timeout` | False | `30` | `aq freeze` Freeze generated artifacts for production integrity checks. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `output` | `--output` | False | `not set` | | Option | `sign` | `--sign` | False | `False` | `aq manifest update` Update manifest with auto-discovered resources. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Argument | `module` | `module` | True | `not set` | | Option | `check` | `--check` | False | `False` | | Option | `freeze` | `--freeze` | False | `False` | `aq inspect routes` Show compiled routes. `aq inspect di` Show DI graph. `aq inspect modules` List all modules. `aq inspect faults` Show fault domains. `aq inspect config` Show resolved configuration. `aq migrate` Migrate from legacy layout. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Argument | `source` | `source` | True | `not set` | | Option | `dry_run` | `--dry-run` | False | `False` | `aq doctor` Diagnose workspace issues. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `as_json` | `--json` | False | `False` | `aq ws inspect` Inspect compiled WebSocket namespaces. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `artifacts_dir` | `--artifacts-dir` | False | `artifacts` | `aq ws broadcast` Broadcast message to namespace or room. | Kind | Name | Flags | Required | Default | | --- | --- | --- | --- | --- | | Option | `namespace` | `--namespace` | True | `not set` | | Option | `room` | `--room` | False | `` | | Option | `event` | `--event` | True | `not set` | | Option | `payload` | `--payload` | False | `{}` | `aq ws gen-client` Generate TypeScript client SDK from compiled WebSocket artifacts. | Kind | Name | Flags | R

### Code Examples
```python
aq init workspace [--minimal] [--template VALUE] [--yes] [NAME]

```

```python
aq add module [--depends-on VALUE] [--fault-domain VALUE] [--route-prefix VALUE] [--with-tests] [--minimal] [--no-docker] [--yes] [NAME]

```

```python
aq generate controller [--prefix VALUE] [--resource VALUE] [--simple] [--with-lifecycle] [--test] [--output VALUE] NAME

```



---

## Framework Docs: docs/installation.md
**URL**: `https://tubox.cloud/docs/framework/docs-installation`

Installation And Setup Requirements Aquilia requires Python `>=3.10` according to `pyproject.toml`. The console script is `aq = aquilia.cli.__main__:main`. Core Install Core dependencies from `pyproject.toml` are `click`, `uvicorn`, `jinja2`, `markupsafe`, `surp`, and `surp`. Optional Extras | Extra | Adds | | --- | --- | | `auth` | `cryptography`, `argon2-cffi` | | `multipart` | `python-multipart` | | `redis` | `redis[asyncio]` for cache/socket backends | | `mail` | `aiosmtplib` | | `mail-ses` | `aiobotocore` | | `mail-sendgrid` | `aquilia.http` | | `server` | `gunicorn`, `uvicorn[standard]` | | `mlops` | `numpy` | | `mlops-onnx` | `onnxruntime`, `onnx` | | `mlops-torch` | `torch` | | `mlops-s3` | `boto3` | | `mlops-bento` | `bentoml` | | `mlops-explain` | `shap`, `lime` | | `testing` | `pytest`, `pytest-asyncio`, `pytest-cov`, `aquilia.http` | | `dev` | `aquilia[testing]`, `ruff`, `mypy`, `pre-commit` | `templates`, `db`, and `files` are compatibility aliases in `pyproject.toml`; Jinja2 is core, database support is native, and native filesystem support lives in `aquilia.filesystem`. First Workspace Operational `aq` commands require `workspace.py` in the current directory except for `init`, `version`, help, and `doctor`. Runtime Entrypoints Development uses `aq run` or `AquiliaServer.run()`. Production containers can use: Set `AQUILIA_WORKSPACE` to the workspace root and `AQUILIA_ENV` to `dev`, `test`, or `prod`.

### Code Examples
```python
pip install aquilia

```

```python
aq init workspace my-api
cd my-api
cp .env.example .env
pip install -r requirements.txt
aq add module users
aq validate
aq run

```

```python
uvicorn aquilia.entrypoint:app --host 0.0.0.0 --port 8000

```



---

## Framework Docs: docs/documentation-coverage-report.md
**URL**: `https://tubox.cloud/docs/framework/docs-documentation-coverage-report`

Documentation Coverage Report This report was produced after the read-only audit and documents the rebuilt markdown set. Source Audit - Python files parsed under `aquilia/`: 540 - Package modules documented: 35 including synthetic `core` - Root core files grouped under `core`: 22 - Mounted Click command/group objects inspected: 129 Rebuilt Documentation Each module now has `README.md`, `architecture.md`, `configuration.md`, `api-reference.md`, `integration-guide.md`, `cli-reference.md`, `examples.md`, `edge-cases-and-limitations.md`, and `troubleshooting.md`. Top-level guides include installation, configuration, full CLI reference, runtime lifecycle, developer guide, examples, operations/security, module index, and this coverage report. Known Documentation Boundaries - API references are AST-derived and focus on public classes/functions/methods plus constants and exports. Private helper bodies are not reproduced line-by-line. - Command references are Click-derived and document mounted `aq` commands. Module-local helper CLIs that are not mounted are called out as such. - Examples use checked repository examples and public APIs visible in source; they avoid inventing project-specific behavior. Modules Covered | Module | Files | Lines | Classes | Functions | Commands Mapped | | --- | ---: | ---: | ---: | ---: | ---: | | `core` | 22 | 27322 | 132 | 46 | 12 | | `admin` | 21 | 26075 | 92 | 53 | 8 | | `aquilary` | 10 | 4676 | 29 | 9 | 12 | | `artifacts` | 6 | 1859 | 19 | 2 | 11 | | `auth` | 24 | 12774 | 164 | 61 | 0 | | `contracts` | 9 | 4728 | 41 | 10 | 0 | | `cache` | 14 | 3813 | 27 | 10 | 4 | | `cli` | 42 | 23184 | 25 | 216 | 104 | | `controller` | 12 | 7813 | 48 | 10 | 0 | | `db` | 9 | 3266 | 15 | 4 | 8 | | `debug` | 2 | 1300 | 1 | 4 | 0 | | `di` | 14 | 4800 | 44 | 16 | 0 | | `discovery` | 2 | 747 | 9 | 0 | 1 | | `faults` | 12 | 4801 | 127 | 23 | 0 | | `filesystem` | 14 | 4317 | 25 | 22 | 0 | | `http` | 17 | 8549 | 100 | 23 | 0 | | `i18n` | 11 | 4190 | 28 | 26 | 6 | | `integrations` | 21 | 2978 | 42 | 0 | 0 | | `mail` | 14 | 4599 | 41 | 9 | 3 | | `middleware_ext` | 8 | 3274 | 22 | 7 | 0 | | `mlops` | 76 | 15885 | 212 | 30 | 24 | | `models` | 33 | 17845 | 222 | 23 | 8 | | `patterns` | 21 | 3246 | 35 | 18 | 0 | | `providers` | 11 | 5882 | 72 | 0 | 16 | | `sessions` | 9 | 3159 | 41 | 3 | 0 | | `sockets` | 14 | 3687 | 41 | 18 | 5 | | `sqlite` | 14 | 2672 | 20 | 8 | 8 | | `storage` | 14 | 3166 | 28 | 2 | 0 | | `subsystems` | 3 | 563 | 4 | 0 | 0 | | `tasks` | 7 | 1802 | 15 | 6 | 0 | | `templates` | 15 | 4409 | 32 | 35 | 0 | | `testing` | 14 | 3874 | 25 | 30 | 1 | | `typing` | 10 | 593 | 37 | 0 | 0 | | `utils` | 4 | 326 | 2 | 2 | 0 | | `versioning` | 11 | 2844 | 30 | 3 | 0 |


---

## Framework Docs: docs/aquilary-registry.md
**URL**: `https://tubox.cloud/docs/framework/docs-aquilary-registry`

Aquilary Module Registry The Aquilary Registry is Aquilia's manifest-driven module discovery and dependency resolution engine. It manages module declarations, checks configuration namespaces, resolves dependencies topologically, indexes route structures, and generates secure cryptographic fingerprints to enable deterministic hot-reloads. To prevent import-time side effects and keep development tooling fast, Aquilia separates registry instantiation into two distinct phases: 1. **Static Validation Phase** (`AquilaryRegistry`): Evaluates manifest declarations without importing controller or service code. It checks route conflicts, resolves dependency cycles, and computes the load order topologically. 2. **Lazy Compilation Phase** (`RuntimeRegistry`): Active only during live ASGI server bootstrapping. Performs runtime package scans, imports user code, compiles route trees, and builds Dependency Injection (DI) containers. --- Core Architecture & Execution Flow --- Phase 1: Static Validation Phase The static phase reads metadata declarations from workspace module manifests and compiles them into a validated layout. No executable code is imported during this phase, meaning errors like syntax bugs or circular imports in your controllers do not crash CLI validation commands (`aq validate` / `aq inspect`). 1. Manifest Loader (`ManifestLoader`) Loads manifest declarations from mixed sources. Sources can be: * Direct Python class references. * File paths to Python manifest files (`manifest.py`). * Domain-Specific Language (DSL) configurations (`manifest.yaml` / `manifest.json`). 2. Registry Validator (`RegistryValidator`) Validates the loaded manifests against configuration namespaces and checks for conflicts: * **Duplicate App Check**: Assures that two modules do not share the same registry name. * **Route Conflict Check**: Scans defined route templates to preemptively flag colliding path patterns. 3. Dependency Graph Resolver (`DependencyGraph`) Constructs an internal directional graph mapping load order dependencies defined by `depends_on`/`imports` tags. It runs a cycle detection check and executes a topological sort to compute the final safe load sequence: If circular references are discovered, it aborts execution and raises a `DependencyCycleError`. 4. Cryptographic Fingerprinting (`RegistryFingerprint`) Generates a SHA-256 hash representing the absolute configuration state: * Hashes manifest properties, configuration namespaces, and file paths. * Incorporates registry mode (`dev`, `prod`, `test`), app count, and route metadata. * Used as a deployment gate. If the server is in `prod` mode and the running registry hash does not match the frozen metadata hash, the deployment is blocked. --- Phase 2: Lazy Compilation Phase The compilation phase is initiated when the live ASGI web server bootstraps. This is where actual user modules are imported and instanced. 1. Auto-Discovery & Scanning (`PackageScanner`) If `auto_discover` is enabled for a module, the `PackageScanner` scans the package directory (`modules.{module_name}`) recursively to identify components: * **Controllers**: Identifies classes subclassing `Controller` or ending in `Controller`. * **Services**: Scans for classes ending in `Service` or decorated with DI annotations. * **Socket Controllers**: Scans for classes decorated with `@Socket`. * **Background Tasks**: Imports `tasks.py` to trigger `@task` registration. * **Models**: Scans the `models/` folder and registers SQL tables with the active database connection. 2. Dependency Injection Bindings Instantiates and registers discovered services in request-scoped DI containers. 3. Route Compilation & Handler Wrapping The `RouteCompiler` compiles route trees from the indexed controller metadata. It imports the target controllers and wraps each endpoint handler in a wrapper: --- Code Example: Registry Bootstrap

### Code Examples
```python
[AppManifest Sources]
         │
         ▼
  [ManifestLoader]      ◄─── Phase 1: Reads declarations (safely, no imports)
         │
         ▼
 [RegistryValidator]    ◄─── Phase 1: Validates schemas & scans route templates
         │
         ▼
  [DependencyGraph]     ◄─── Phase 1: Detects cycle errors & sorts modules topologically
         │
         ▼
 [AquilaryRegistry]     ◄─── Phase 1: Produces RegistryFingerprint (frozen metadata)
         │
         ▼
 [RuntimeRegistry]      ◄─── Phase 2: Server bootstrap triggers lazy compilation
         │
         ▼
  [PackageScanner]      ◄─── Phase 2: Recursively scans module package files
         │
         ▼
  [RouteCompiler]       ◄─── Phase 2: Imports controllers, binds DI containers

```

```python
# topological_sort computes the load order:
# For graph A -> B, A loads first, then B.
load_order = dep_graph.topological_sort()

```

```python
# Binds request-scoped DI container to handler arguments
route.handler = wrap_handler(route.handler, container)

```



---

## Framework Docs: docs/mcp/examples.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-examples`

MCP Examples Search Runtime APIs Call `find_api` to locate runtime source, docs, and tests before editing startup behavior. Validate A Module Plan Call `validate_manifest_plan` before writing workspace or manifest code. It flags deprecated `Module.register_*`, `AppManifest.route_prefix`, `AppManifest.database`, YAML config, and raw framework-domain exception patterns. Generate An Agent Prompt The prompt includes current Aquilia conventions, anti-pattern guards, expected file shapes, source anchors, and validation steps. Find Aquilia APIs List Agent-Facing Tools Build A Prompt Use the `generate_agent_prompt` tool with: The generated prompt includes source-backed anchors, anti-pattern guards, expected file shape, and validation steps.

### Code Examples
```python
{"query": "AquiliaRuntime bootstrap", "limit": 5}

```

```python
{
  "plan": "Workspace('shop').module(Module('orders').route_prefix('/orders')); AppManifest(name='orders', controllers=[...])"
}

```

```python
{"workflow": "aquilia.add_db_models_migrations", "goal": "Add inventory models and migrations"}

```



---

## Framework Docs: docs/mcp/architecture.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-architecture`

MCP Architecture The server has four layers: 1. `aquilia.mcp.context` scans and indexes `aquilia/**/*.py`, `docs/**/*.md`, `examples/**/*`, and `tests/**/test_*.py`. 2. `aquilia.mcp.registry` exposes deterministic tools and prompts with strict schemas. 3. `aquilia.mcp.server.AquiliaMCPServer` maps MCP JSON-RPC methods to registry calls and resource/prompt access. 4. `aquilia.mcp.transport.stdio` provides bounded newline-delimited JSON-RPC over stdin/stdout. The index extracts symbols, anchors, imports, sections, summaries, deprecations, CLI metadata, example mappings, and source-backed architecture facts. It stores a deterministic content fingerprint and a lightweight tree fingerprint so unchanged repositories can reuse the persisted index. The runtime flow described by the tools follows the actual source path: `aquilia.entrypoint` -> `AquiliaRuntime.configure()` -> `discover()` -> `bootstrap()` -> `AquiliaServer` -> `Aquilary` / `RuntimeRegistry` -> `ASGIAdapter`. Protocol The stdio server supports `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`, `resources/read`, `prompts/list`, and `prompts/get`. JSON-RPC parsing preserves request IDs, ignores notifications that do not require replies, maps unknown methods to `-32601`, and maps Aquilia/MCP faults into structured error data. Security The MCP layer is read-only by default. It does not expose shell execution or file mutation tools. Resource reads are limited to the configured root, reject absolute paths and traversal, redact secret-like lines in indexed text, and cap read sizes.


---

## Framework Docs: docs/mcp/troubleshooting.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-troubleshooting`

MCP Troubleshooting `mcp.root` Is Invalid Run commands from the repository root or pass `--workspace /path/to/Aquilia`. The root must contain an `aquilia/` directory. Tool List Is Empty Rebuild the index and run doctor: Agent Cannot Start Server Confirm the command works directly: For old configs, `python -m aquilia.mcp` is still supported. Resource Read Fails `resources/read` only accepts `aquilia://relative/path` URIs or relative paths under the configured root. Binary files, directories, absolute paths, missing files, and traversal outside the root are blocked. Stale Results The index is reused when the source tree fingerprint is unchanged. Pass `--force` to rebuild when debugging suspicious search results. No tools appear Run: Confirm the workspace path points at a repository root containing `aquilia/`. Agent cannot start the server Run the configured command manually: It should wait for JSON-RPC input on stdin. Index is stale Run: Resource read fails Only relative `aquilia://...` URIs inside the configured root are allowed.

### Code Examples
```python
aq mcp build-index --workspace . --force
aq mcp doctor --json

```

```python
python -m aquilia.mcp --stdio --workspace .

```

```python
aq mcp doctor --json

```



---

## Framework Docs: docs/mcp/integration-guide.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-integration-guide`

MCP Integration Guide Local Server Command Use this command in local agents: `aq mcp install` writes this command for Claude, Codex, and Gemini CLI configs. The installer is idempotent and supports `--dry-run` and `--verify`. Agent Use Ask agents to call MCP tools before generating Aquilia code. The most useful first calls are: - `explain_bootstrap` for runtime and request lifecycle. - `find_api` for source symbols and docs. - `validate_manifest_plan` before writing workspace or manifest code. - `deprecation_guard` when adapting older snippets. - `find_examples` to locate runnable reference applications. Compatibility `aquilia.mcp` remains importable for older local configs, but new configs should use `aquilia.mcp`. Claude Desktop Codex Gemini CLI Each adapter registers:

### Code Examples
```python
{
  "command": "python",
  "args": ["-m", "aquilia.mcp", "--stdio", "--workspace", "/path/to/Aquilia"]
}

```

```python
aq mcp install --agent claude --dry-run
aq mcp install --agent claude --verify

```

```python
aq mcp install --agent codex --dry-run
aq mcp install --agent codex --verify

```



---

## Framework Docs: docs/mcp/README.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-README`

Aquilia MCP Aquilia MCP is a local, read-only Model Context Protocol server for coding agents working on Aquilia projects. It indexes the actual repository source, docs, examples, and tests, then exposes source-backed tools and prompts for Aquilia-aware generation, validation, discovery, and debugging. The canonical package is `aquilia.mcp`; `aquilia.mcp` remains as a compatibility import path. Quick Start The server identity remains `aquilia-mcp`. Tools - `find_api`: search symbols, docs, examples, and tests. - `explain_bootstrap`: explain runtime/server/ASGI flow from source anchors. - `suggest_architecture`: propose manifest-first workspace/module structure. - `scaffold_workspace`: return a read-only workspace scaffold plan. - `scaffold_module`: return a read-only module scaffold plan. - `validate_manifest_plan`: catch deprecated or incorrect Aquilia patterns. - `recommend_integrations`: map feature goals to current Integration/Workspace APIs. - `deprecation_guard`: flag deprecated APIs in snippets or plans. - `list_cli_commands`: list the mounted Click command tree. - `find_examples`: find runnable examples by feature. - `generate_agent_prompt`: render source-backed workflow prompts. Design Rules - Source code is the source of truth. - `workspace.py` handles workspace orchestration. - `modules/<name>/manifest.py` handles module internals. - `Module.register_*`, `AppManifest.database`, and `AppManifest.route_prefix` are treated as deprecated. - MCP tools are read-only and do not expose arbitrary shell execution. - Resource reads reject path traversal, null bytes, missing files, directories, and binary files.

### Code Examples
```python
aq mcp build-index --workspace .
aq mcp doctor --json
aq mcp list-tools
python -m aquilia.mcp --stdio --workspace .

```



---

## Framework Docs: docs/mcp/cli-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-cli-reference`

MCP CLI Reference All commands are mounted under `aq mcp` from `aquilia/cli/commands/mcp.py` and use the canonical server package `aquilia.mcp`. Serve Starts the local MCP server over stdio. `--workspace` points at the repository or workspace root. `--index` selects a persisted index file. Build Index Builds or refreshes the persistent source index. Without `--force`, unchanged trees reuse the existing index. Doctor Checks that the index can be loaded, tools/prompts are registered, and the server can be constructed. Install Patches the local agent config idempotently, preserving a backup when an existing file is changed. `--verify` constructs the server and confirms that a non-empty tool list is reachable. Discovery These commands expose the same registry and search behavior available through MCP clients. `serve` uses stdio and is intended for local agent configs. `build-index` writes `.aquilia/mcp/index.json` by default. `install` patches the selected agent config idempotently and backs up existing config before writing.

### Code Examples
```python
aq mcp serve --workspace . --stdio --index .aquilia/mcp/index.json

```

```python
aq mcp build-index --workspace . --force

```

```python
aq mcp doctor --json

```



---

## Framework Docs: docs/mcp/security.md
**URL**: `https://tubox.cloud/docs/framework/docs-mcp-security`

MCP Security Aquilia MCP is read-only by default. Boundaries - No arbitrary shell execution tools are registered. - Tools return plans, validation, source anchors, and prompts; they do not write application files. - Resource reads must resolve under the configured workspace root. - Absolute paths, `..` traversal, null bytes, directories, missing files, and known binary extensions are rejected. - Indexed text redacts secret-like lines containing markers such as `password`, `secret`, `token`, `api_key`, or `credential`. - Request and resource sizes are bounded by `MCPConfig`. Installer Behavior Installers only patch local JSON config files for the selected agent. Existing configs are backed up before write. Dry-run returns the proposed config without writing. Diagnostics `aq mcp doctor --json` reports tool, prompt, source, and fingerprint metadata without dumping indexed source text or environment variables. Aquilia MCP is read-only by default. Security controls: - Resource reads are sandboxed to the configured root. - Null-byte and path traversal attempts are rejected. - Binary and generated artifacts are excluded from the source index. - Tool inputs are schema-validated. - Tool outputs are bounded and deterministic. - Secret-like lines are redacted from indexed snippets. - The server does not expose shell execution or file mutation tools. Installer commands modify only local agent configuration files and keep timestamped backups.


---

## Framework Docs: docs/docs/index.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-index`

--- title: "Aquilia Documentation" description: "Welcome to the Aquilia framework documentation" icon: lucide/home --- Overview Welcome to the documentation for Aquilia, a Python web framework. This documentation covers two primary architectural modules of the framework: 1. **[Controllers](controller/index.md)**: A class-based, dependency-injection-first request routing and execution layer that replaces traditional function-based handlers. 2. **[Contracts](contracts/index.md)**: A model-to-world contract system that declares data casting, sealing (validation), and imprinting (persistence) flows. --- Key Modules Controller Module !!! info Evidence: `aquilia/controller/__init__.py:4-12` The Controller module provides class-based routing, compile-time metadata extraction, automatic parameter validation, content negotiation, pagination, filtering, and rate limiting. Contracts Module !!! info Evidence: `aquilia/contracts/__init__.py:4-7` The Contracts module provides a system to define declarative schemas (specs), input type coercion (casts), cross-field validators (wards), relationship traversal (lenses), dynamic sub-selections (projections), and serialization mappings.


---

## Framework Docs: docs/docs/contracts/exceptions.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-exceptions`

--- title: "Contract Exceptions" description: "Detailed guide to the ContractFault error hierarchy and fault domain in Aquilia" icon: lucide/alert-triangle --- Overview All validation and execution errors in Contracts participate in Aquilia's unified fault domain system. They inherit from a common base class, `ContractFault`, and provide structured payloads for API error responses. --- The CONTRACT Fault Domain !!! info Evidence: `aquilia/contracts/exceptions.py:16-19` Aquilia groups Contract-related errors under a single fault domain [CONTRACT](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L16-L19). --- Base Exception: ContractFault !!! info Evidence: `aquilia/contracts/exceptions.py:25-57` [ContractFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L25-L57) is the base exception class for all Contract errors. It inherits from `Fault` and exposes the following settings: - **Domain**: [CONTRACT](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L16-L19) - **Severity**: `Severity.ERROR` - **Default Code**: `"BP000"` - **Public**: `True` (meaning it is safe to return to API clients) Signature JSON Response Format The [as_response_body](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L48-L56) method converts the exception into a structured payload for HTTP responses: --- Specific Contract Exceptions CastFault (BP100) !!! info Evidence: `aquilia/contracts/exceptions.py:62-80` Raised when incoming data cannot be coerced into the type required by the field's Facet. - **Fault Code**: `BP100` - **Key attributes**: `field` (name of the field that failed casting) - **Example payload**: --- SealFault (BP200) !!! info Evidence: `aquilia/contracts/exceptions.py:82-109` Raised when one or more validation constraints are broken during the contract sealing phase (such as custom `@ward` methods or facet validation constraints). - **Fault Code**: `BP200` - **Key attributes**: `field_errors` (mapping of field names to their validation error lists) - **Error details construction**: If a single field fails, it populates `metadata["details"]` with `{"field": ..., "reason": ...}`. For multiple fields, it populates `{"fields": [{"field": ..., "reasons": ...}, ...]}`. --- ImprintFault (BP300) !!! info Evidence: `aquilia/contracts/exceptions.py:111-115` Raised when writing (imprinting) validated data back to the database or model instance fails. - **Fault Code**: `BP300` --- ProjectionFault (BP400) !!! info Evidence: `aquilia/contracts/exceptions.py:117-127` Raised when a projection requested by name is not found in the contract spec. - **Fault Code**: `BP400` - **Key attributes**: `projection` (the requested projection name), `available` (list of valid projection names configured in the Spec) --- LensDepthFault (BP500) !!! info Evidence: `aquilia/contracts/exceptions.py:129-139` Raised when traversing nested relationships using Lenses exceeds the configured maximum depth limit. - **Fault Code**: `BP500` - **Key attributes**: `path` (traversal path where the limit was hit), `max_depth` (the maximum allowed depth limit) --- LensCycleFault (BP501) !!! info Evidence: `aquilia/contracts/exceptions.py:141-150` Raised when a circular reference loop is detected during Lens modeling. - **Fault Code**: `BP501` - **Key attributes**: `cycle_path` (the list of fields showing the cycle loop, e.g., `["author", "posts", "author"]`) --- Code Example Catching and responding with Contract validation faults:

### Code Examples
```python
CONTRACT = FaultDomain(
    name="CONTRACT",
    description="Contract contract violations -- casting, sealing, imprinting",
)

```

```python
def __init__(
    self,
    message: str = "Contract validation failed",
    *,
    errors: dict[str, list[str]] | None = None,
    code: str | None = None,
    metadata: dict[str, Any] | None = None,
):

```

```python
{
  "fault": "BP000",
  "message": "Contract validation failed",
  "errors": {
    "field_name": ["Error message"]
  }
}

```



---

## Framework Docs: docs/docs/contracts/lenses.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-lenses`

--- title: "Lenses" description: "Modeling nested resource mappings and relationship traversal in Contracts" icon: lucide/glasses ---A [Lens](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26-L184) is a relational facet that views related data through another [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826-L2075). It lets a contract expose related model data with depth control, cycle detection, and projection selection. 1. What is a Lens? (Optical Metaphor) The term **Lens** is used as an optical metaphor because it provides a focused *view* into related data, similar to how an optical lens adjusts focus, zoom, and magnification to show nested objects clearly ([lenses.py:L7-10](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L7-L10)). A [Lens](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26-L184) inherits from [Facet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L228-L457) ([lenses.py:L26](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26)) and serves as a depth-controlled relational view. --- 2. Constructor Parameters The [Lens](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26-L184) constructor accepts the following parameters ([lenses.py:L52-59](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L52-L59)): | Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | `target` | `type[Contract] \| _ProjectedRef \| None` | `None` | The target Contract class or subscripted projection used to format the related data ([lenses.py:L54](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L54)). | | `many` | `bool` | `False` | When `True`, the lens expects an iterable sequence of objects and molds each item individually ([lenses.py:L56](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L56)). | | `depth` | `int` | `3` | Maximum nesting depth limit for resolving related lenses before falling back to ID representation ([lenses.py:L57](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L57)). | | `projection` | `str \| None` | `None` | Named projection of the target Contract to restrict/change the exposed fields ([lenses.py:L58](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L58)). | | `source` | `str \| None` | `None` | (Keyword-only from `**kwargs`) The model attribute or dotted path to extract the relation data from ([lenses.py:L59](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L59)). | | `read_only` | `bool` | `True` | (Keyword-only from `**kwargs`) Determines if the field is read-only. Lenses default to `True` ([lenses.py:L61](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L61)). | --- 3. Subscript Projections & `_ProjectedRef` When specifying target Contracts, you can select specific projections using Python's subscript syntax (e.g., `UserContract["public"]`). Under the hood, this subscript returns an instance of [_ProjectedRef](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L187-L201) ([lenses.py:L187-201](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L187-L201)). - The [_ProjectedRef](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L187-L201) class stores `contract_cls` and the string `projection` name ([lenses.py:L194-198](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L194-L198)). - The [Lens](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26-L184) constructor unpacks it automatically ([lenses.py:L65-70](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L65-L70)): --- 4. Depth Control Lenses prevent infinite recursion by enforcing a maximum recursion depth limit, configured via `depth` constructor parameter (stored as `self.max_depth`) ([lenses.py:L73](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L73)). - The `mold()` method takes an internal `_depth` parameter tracking the current nesting level ([lenses.py:L93](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L93)). - During recursive resolution, `_depth` increments by 1: `_depth=_depth + 1` ([lenses.py:L132-133](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L132-L133)). - Once `_depth >= self.max_depth`, resolution halts and falls back to primary key extraction ([lenses.py:L118-122](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L118-L122)): --- 5. Cycle Detection To prevent cyclic references where contracts link back to themselves (either directly or transit

### Code Examples
```python
# Lenses are read-only by default (lenses.py:L61)
kwargs.setdefault("read_only", True)
super().__init__(**kwargs)

```

```python
if isinstance(target, _ProjectedRef):
    self._target_cls = target.contract_cls
    self._projection = target.projection
else:
    self._target_cls = target
    self._projection = projection

```

```python
if _depth >= self.max_depth:
    if self.many:
        return [self._pk_fallback(item) for item in value]
    return self._pk_fallback(value)

```



---

## Framework Docs: docs/docs/contracts/casting-sealing.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-casting-sealing`

--- title: "Casting, Sealing & Lifecycle" description: "Understanding the three-phase data lifecycle of Contracts: Cast, Seal, and Imprint" icon: lucide/lock --- Every Aquilia Contract guides inbound data through a deterministic, multi-phase lifecycle before it ever reaches a persistent state or model. This ensures strict validation, clear error domains, and robust guarantees at the database boundary. --- 1. The Three-Phase Lifecycle The Contract data pipeline operates in three distinct phases: **Cast**, **Seal**, and **Imprint**. --- 2. The Cast Phase The **Cast Phase** is the first line of defense. It parses raw inbound data structures and coerces values into their corresponding Python type representations. If a value cannot be coerced to the expected type, a [CastFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L62-L80) is raised. Type Coercion by Facet Each facet implements its coercion logic within its `cast()` method: * **`Facet`** ([facets.py:L325-332](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L325-L332)): The base facet simply returns the incoming value as-is without any modification. * **`TextFacet`** ([facets.py:L507-519](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L507-L519)): Coerces strings and safe primitive types (integers, floats, booleans) to strings. If `trim=True` (default), it strips whitespace. Raises `CastFault` for complex types. * **`EmailFacet`** ([facets.py:L548-550](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L548-L550)): Inherits from `TextFacet` but lowercases the cast string. * **`IntFacet`** ([facets.py:L644-650](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L644-L650)): Coerces inputs using `int()`. Booleans are explicitly rejected to prevent `True` / `False` casting to `1` / `0`. * **`FloatFacet`** ([facets.py:L695-706](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L695-L706)): Coerces inputs using `float()`. Rejects `NaN` and `Infinity` values unless explicitly allowed via `allow_nan` or `allow_infinity`. * **`DecimalFacet`** ([facets.py:L749-755](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L749-L755)): Parses string and numeric inputs into Python `Decimal` objects. * **`BoolFacet`** ([facets.py:L797-811](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L797-L811)): Resolves values to booleans. Supports boolean types, integer-matching (`1`/`0`), and truthy/falsy strings (e.g., `"true"`, `"yes"`, `"on"` / `"false"`, `"no"`, `"off"`). * **`DateFacet`** ([facets.py:L822-832](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L822-L832)): Parses ISO 8601 strings into standard `date` objects, or extracts the date part from a `datetime` instance. * **`DateTimeFacet`** ([facets.py:L880-891](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L880-L891)): Parses ISO 8601 strings (handling trailing `"Z"` offsets) into `datetime` objects. * **`DurationFacet`** ([facets.py:L911-935](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L911-L935)): Parses numerical inputs (treated as seconds) or `"HH:MM:SS"` string formats into `timedelta` objects. * **`ListFacet`** ([facets.py:L995-1010](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L995-L1010)): Ensures the input value is a list or tuple. If a `child` facet is configured, it recursively casts every element. * **`DictFacet`** ([facets.py:L1189-1222](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1189-L1222)): Verifies inputs are dictionary-like and keys are strings. Parses JSON string representations starting with `{`. Restricts key count to prevent Hash DoS (using `max_keys`). Recursively casts values if `value_facet` is supplied. * **`ChoiceFacet`** ([facets.py:L1364-1365](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1364-L1365)): Passes the value through unchanged during casting (membership checks are deferred to the Seal Phase). * **`EnumFacet`** ([facets.py:L1402-1429](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1402-L1429)): Looks up and returns the corresponding enum member by matching the value against member names or values. --- 3. The Seal Phase The **Seal Phase** enforces contract validation, ensuring that data is complete, meets validation constraints, and respects business rules. Once sealed, a Contract yields a read-only, validated data object. Facet Seal Constraints During `seal()`, each facet runs specific constraint checks: * **`Facet`** ([facets.py:L346-360](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L346-L360)): Evaluates all registered custom validators. * **`TextFacet`** ([fa

### Code Examples
```python
mermaid
graph TD
    %% Styling
    classDef phase fill:#2a2b36,stroke:#7c3aed,stroke-width:2px,color:#fff;
    classDef success fill:#064e3b,stroke:#059669,stroke-width:1px,color:#fff;
    classDef fail fill:#7f1d1d,stroke:#dc2626,stroke-width:1px,color:#fff;

    RawData[Inbound Raw Data] --> PhaseCast[Phase 1: Cast<br/>Type Coercion & Coarse Validation]:::phase
    
    PhaseCast -->|Cast Error| CastErr[CastFault / BP100]:::fail
    PhaseCast -->|Success| CoercedData[Coerced Python Values]
    
    CoercedData --> PhaseSeal[Phase 2: Seal<br/>Constraint Checks, Wards & Hook Validation]:::phase
    
    PhaseSeal -->|Seal Error| SealErr[SealFault / BP200]:::fail
    PhaseSeal -->|Success| SealedData[Sealed Validated Data]
    
    SealedData --> PhaseImprint[Phase 3: Imprint<br/>Write, Create or Update Model]:::phase
    
    PhaseImprint -->|Imprint Error| ImprintErr[ImprintFault / BP300]:::fail
    PhaseImprint -->|Success| ModelInstance[Saved Model Instance]:::success

```

```python
mermaid
sequenceDiagram
    participant B as Contract (is_sealed)
    participant S as Sigil (validate)
    participant W as Wards (_ward_methods)
    participant H as Hook (validate)

    B->>S: 1. Structural casting & validation
    S-->>B: Return errors & validated_dict
    Note over B: Stop if structural errors found
    
    B->>W: 2. Run sync ward methods wm.fn()
    W-->>B: Capture CastFault or exceptions
    Note over B: Stop if ward errors found
    
    B->>H: 3. Run final object validate() hook
    H-->>B: Return final data dict
    Note over B: Mark sealed (is_sealed = True)

```

```python
@dataclass(frozen=True, slots=True)
    class SealOutcome:
        index: int
        ok: bool
        value: dict | None
        errors: dict | None
    
```



---

## Framework Docs: docs/docs/contracts/integration.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-integration`

--- title: "Integration Helpers" description: "Helper functions to integrate Contracts with the Aquilia Controller framework" icon: lucide/cable ---Aquilia provides a set of integration helpers in [integration.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/integration.py) to bridge the gap between Contract definitions, request/response lifecycle hooks, dependency injection (DI), and the Controller engine. --- Detection Utilities `is_contract_class()` Check if an object is a class definition inheriting from `Contract` (excluding the base `Contract` class itself). Signature Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `obj` | `Any` | | The object to check. | Return Type - `bool`: `True` if the object is a subclass of `Contract` (excluding `Contract` itself), otherwise `False`. When to Use Use this function during route initialization, dependency injection container setup, or annotation parsing to detect whether a route parameter is typed as a Contract class. > [!NOTE] > Defined in [integration.py:L46-49](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/integration.py#L46-L49). --- `is_projected_contract()` Check if an object is a projected Contract reference (`_ProjectedRef`), typically represented as `Contract["projection"]`. Signature Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `obj` | `Any` | | The object to check. | Return Type - `bool`: `True` if the object is an instance of `_ProjectedRef`, otherwise `False`. When to Use Use this function when verifying type annotations to identify if a specific projection of a Contract class is being requested. > [!NOTE] > Defined in [integration.py:L51-54](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/integration.py#L51-L54). --- `resolve_contract_from_annotation()` Extract the underlying `Contract` class and any associated projection name from a type annotation. Signature Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `annotation` | `Any` | | The type annotation to inspect/resolve. | Return Type - `tuple[type[Contract] | None, str | None]`: A tuple containing: 1. The resolved `Contract` class or `None` if not a Contract annotation. 2. The name of the projection, or `None` if no projection is applied. When to Use Use this helper during controller configuration to extract Contract schema details from method parameter annotations. It correctly handles: - Raw Contracts (`MyContract` &rarr; `(MyContract, None)`) - Projected Contracts (`MyContract["summary"]` &rarr; `(MyContract, "summary")`) - Non-contract types (&rarr; `(None, None)`) > [!NOTE] > Defined in [integration.py:L56-76](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/integration.py#L56-L76). --- Lifecycle Binding `bind_contract_to_request()` Instantiate, merge parameters from, and validate a `Contract` from an incoming HTTP request. Signature Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `contract_cls` | `type[Contract]` | | The Contract class to instantiate. | | `request` | `Any` | | The incoming Aquilia HTTP request object. | | `projection` | `str \| None` | `None` | Optional projection name to restrict or filter validated data. | | `partial` | `bool` | `False` | If True, fields not supplied in the request are ignored (useful for PATCH routes). | | `context` | `dict[str, Any] \| None` | `None` | Extra context mapping (e.g. dependency injection container info) to supply to the ContractContext. | Return Type - `Contract`: An instantiated Contract instance with input data merged and validation executed (the instance will have been sealed). When to Use This is the core integration point between the controller execution engine and the Contract framework. It is invoked when a controller endpoint receives an incoming request containing an annotated Contract argument. The function extracts values from JSON payloads, form data, file uploads, query parameters, headers, cookies, and path parameters, and merges them into a single validation mapping. > [!IMPORTANT] > The function implements security limits such as verifying the request content length against `MAX_BODY_SIZE` (default 10 MB, configurable via context) to prevent resource exhaustion attacks. > > Defined in [integration.py:L298-538](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/integration.py#L298-538). --- `render_contract_response()` Render Python model instances or lists of data using a designated Contract for client response output. Signature Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `contract_or_cls` | `Contract \| type[Contract]` | | An existing Contract instance, a Contract class, or a projected Contract reference. | | `data` | `Any` | `None` | The data to render (a single model instance, dictionary, or a collection of elements). | | `projectio

### Code Examples
```python
def is_contract_class(obj: Any) -> bool:

```

```python
def is_projected_contract(obj: Any) -> bool:

```

```python
def resolve_contract_from_annotation(
    annotation: Any,
) -> tuple[type[Contract] | None, str | None]:

```



---

## Framework Docs: docs/docs/contracts/blueprint-union.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-blueprint-union`

--- title: "Contract Unions" description: "Handling polymorphic types and union schemas with ContractUnion" icon: lucide/merge ---`ContractUnion` is a compiled discriminated union wrapper constructed via the bitwise OR (`|`) operator on Contracts. It is defined in [core.py:L676-787](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L676-787). It is designed to handle polymorphic types, polymorphic responses, and union schemas dynamically. --- What is ContractUnion The [ContractUnion](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L676-787) class wraps multiple member Contracts to provide a unified validation and schema generation interface. - **Bitwise Construction**: It is constructed when combining Contracts using the `|` operator (e.g., `UserContract | AdminContract`), which is implemented via `__or__` ([core.py:L772-775](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L772-775)) and `__ror__` ([core.py:L777-778](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L777-778)). - **Low Memory Overhead**: Utilizes python `__slots__` containing `("members", "discriminator_field", "_dispatch")` ([core.py:L679](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L679)) to prevent dynamic dict creation. --- Constructor and API Constructor *Citations: [core.py:L681-683](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L681-683)* When initialized, the union attempts to construct a dispatch mapping by locating or auto-detecting a discriminator field among its members. Core Methods `validate(self, data: Any) -> tuple[dict, dict]` Validates incoming data against the union's members. - **Discriminated dispatch**: If a discriminator mapping exists, it retrieves the discriminator value from the input dictionary and routes the validation to the matching Contract's `_sigil.validate(data)` method ([core.py:L748-756](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L748-756)). - **Try-Each Fallback**: If no discriminator mapping is defined, it loops through each member Contract, attempting validation. The first member that validates without errors is selected ([core.py:L766-769](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L766-769)). If all fail, it returns a union mismatch error ([core.py:L770](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L770)). *Citations: [core.py:L743-770](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L743-770)* `to_json_schema(self) -> dict` Generates a JSON schema representation of the union using the `oneOf` schema combiner with all members' schemas. If a discriminator field exists, it includes OpenAPI/JSON Schema compatible discriminator mapping metadata. *Citations: [core.py:L780-787](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L780-787)* --- Dispatch and Auto-Detection The `_build_dispatch(self)` method resolves how input data is routed ([core.py:L685-741](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L685-741)): 1. **Explicit Discriminator Check**: First checks if any member Contract has defined an explicit discriminator via its configuration spec (`Spec.discriminator`) ([core.py:L688-692](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L688-692)). 2. **Implicit Discriminator Auto-Detection**: If not explicitly set, scans all facets defined in all member Contracts. It searches for a common field present across all members where: - The field is a `ChoiceFacet` ([core.py:L700-703](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L700-703)). - The allowed values of the `ChoiceFacet` across all members are completely disjoint (unique per member) ([core.py:L711-726](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L711-726)). 3. **Dispatch Table Building**: Maps each disjoint value to its respective member Contract class ([core.py:L728-739](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L728-739)). !!! warning If no discriminator field can be found, the union falls back to try-each validation. This invokes `validate()` sequentially on each member contract, which can be computationally expensive and raises a `RuntimeWarning` ([core.py:L757-765](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L757-765)). --- When to Use It 1. **Polymorphic Responses**: Use when your API endpoints return different schemas under different circumstances (e.g., a successful resource payload versus an error payload, or differing types of media entities). 2. **Discriminated Unions / Heterogeneous Payloads**: Use when parsing payloads representing different subtypes (e.g., paying via `CreditCard` versus `PayPal` in a paym

### Code Examples
```python
def __init__(self, members: tuple):
    self.members = members
    self.discriminator_field, self._dispatch = self._build_dispatch()

```

```python
from typing import Literal
from aquilia.contracts import Contract
from aquilia.contracts.facets import ChoiceFacet

# 1. Define distinct polymorphic member contracts
class CreditCardPayment(Contract):
    # Kind facet with unique value triggers auto-detection
    type = ChoiceFacet(allowed_values=("credit_card",))
    card_number: str
    expiration: str

class PayPalPayment(Contract):
    type = ChoiceFacet(allowed_values=("paypal",))
    email: str

# 2. Combine contracts using the | operator
PaymentUnion = CreditCardPayment | PayPalPayment

# 3. Validation handles dispatching dynamically based on the 'type' field
errors, validated = PaymentUnion.validate({
    "type": "paypal",
    "email": "user@example.com"
})
# Successfully validated against PayPalPayment

# 4. Unknown type results in validation error
errors, validated = PaymentUnion.validate({
    "type": "bank_transfer",
    "account": "123456789"
})
# errors contains: {"type": ["Unknown discriminator value: 'bank_transfer'"]}

```



---

## Framework Docs: docs/docs/contracts/facets.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-facets`

--- title: "Facets" description: "Detailed catalog of all built-in validation, type coercion, and injection facets in Aquilia" icon: lucide/gem --- What is a Facet? In Aquilia, a **Facet** is the field-level primitive of a `Contract` ([facets.py:L2](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L2)). A [Facet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L228-L458) represents a single aspect of a model exposed through a `Contract` ([facets.py:L4](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L4)). Facets can auto-derive from model fields, but they can also be overridden, composed, or created standalone ([facets.py:L5-L6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L5-L6)). It replaces traditional serialization field abstractions with clean, Contract-native semantics defined across three primary stages ([facets.py:L11-L12](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L11-L12)): * **Inbound Cast**: Raw request data is processed, type-coerced, and parsed into Python objects ([facets.py:L325-L332](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L325-L332)). * **Inbound Validation (Seal)**: The cast Python objects are validated against constraints and user-defined validation callables ([facets.py:L346-L360](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L346-L360)). * **Outbound Mold**: Attributes from internal model instances are shaped, normalized, and formatted for the outbound response ([facets.py:L336-L342](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L336-L342)). --- Base Facet API Every built-in facet inherits from the base [Facet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L228-L458) class. Parameters & Defaults The [Facet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L228-L458) base constructor accepts the following parameters ([facets.py:L256-L280](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L256-L280)): | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `source` | `str \| None` | `None` | Model attribute name to read from. Defaults to the facet\ | | `required` | `bool \| None` | `None` | Specifies if the field is mandatory in inbound requests. If None, it is dynamically computed based on defaults and nullability (facets.py:L291-L299). | | `read_only` | `bool` | `false` | If True, the facet only appears in outbound responses and is ignored during inbound casting (facets.py:L272). | | `write_only` | `bool` | `false` | If True, the facet is only accepted in inbound requests and is omitted from outbound serialization (facets.py:L273). | | `default` | `Any` | `UNSET` | Default value used if the key is missing from inbound data. Uses the UNSET sentinel (facets.py:L274). | | `allow_null` | `bool` | `false` | If True, None is accepted as a valid cast value (facets.py:L275). | | `allow_blank` | `bool` | `false` | If True, empty strings are allowed in text-based facets (facets.py:L276). | | `label` | `str \| None` | `None` | A human-readable label for documentation and form generation (facets.py:L277). | | `help_text` | `str \| None` | `None` | Documentation string explaining the field\ | | `validators` | `Sequence[Callable] \| None` | `None` | List of additional validation callables that run during seal() (facets.py:L279). | Life-Cycle Methods A [Facet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L228-L458) processes data using several standard lifecycle methods: * **`cast(value: Any) -> Any`** ([facets.py:L325-L332](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L325-L332)) Coerces raw inbound input to the correct Python type. Overridden by subclasses to perform specific type checks and parsing. Raises `CastFault` on failure. * **`seal(value: Any) -> Any`** ([facets.py:L346-L360](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L346-L360)) Validates a cast value against constraints and runs custom callables in `self.validators`. Raises `CastFault` (wrapping `ValueError` or `TypeError`) if validation fails. * **`mold(value: Any) -> Any`** ([facets.py:L336-L342](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L336-L342)) Converts internal Python values into JSON-serializable formats for outbound responses. * **`extract(instance: Any) -> Any`** ([facets.py:L364-L392](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L364-L392)) Extracts the raw attribute from a model instance. Supports dotted strings (e.g., `user.profile.avatar`) and extracts values from nested dictionaries or contracts safely. If `source="*"`, the entire instance is returned. * **`bind(nam

### Code Examples
```python
username_facet = TextFacet()[3:20] # min_length=3, max_length=20
    int_range_facet = IntFacet()[0:100:5] # min_value=0, max_value=100, multiple_of=5
    
```

```python
username = Facet.text[3:20]
    
```

```python
percent = Facet.int[0:100:5]
    
```



---

## Framework Docs: docs/docs/contracts/sigil.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-sigil`

--- title: "Sigil & FieldSpec" description: "Understanding the Sigil pattern and FieldSpec configuration in Contracts" icon: lucide/stamp ---Overview A **Sigil** is the compiled, immutable representation of a Contract validation schema ([sigil.py:L4-6, L102](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L4-L6)). It is compiled exactly once per Contract class definition and cached as `cls._sigil` ([sigil.py:L4](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L4)). A **FieldSpec** represents the compiled specification of a single field within the Sigil schema ([sigil.py:L64](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L64)). --- Relationship to Contract Field Declarations When a Contract class is defined, the compilation process constructs a `Sigil` using [build_sigil](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L939-L981): 1. **Facet Processing**: The compiler iterates over the facets found in `cls._all_facets.items()` ([sigil.py:L945](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L945)). 2. **Metadata Flags**: - It checks whether each facet wraps a nested Contract (`NestedContractFacet` or `LazyContractFacet`) ([sigil.py:L946](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L946)). - It determines if a facet represents a Lens field (`Lens`) ([sigil.py:L947](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L947)). 3. **Pipeline Extraction**: It extracts any pipeline configurations registered during annotations parsing (`getattr(facet, "_pipeline", None)`) ([sigil.py:L950](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L950)). 4. **FieldSpec Construction**: It builds a [FieldSpec](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L63-L99) mapping for the field name with all validation parameters (facet constraints, defaults, pipelines, etc.) ([sigil.py:L952-L961](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L952-L961)). 5. **Schema Spec Mapping**: It reads schema-level specifications from `cls._spec` ([sigil.py:L964-L969](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L964-L969)): - `strict`: Whether validation operates in strict mode by default. - `revision`: Schema revision identifier. - `migrate_from`: Map of prior schema revisions to migration callbacks. - `migrate_step`: Sequence-based migration callback on `cls`. - `discriminator`: Field name denoting polymorphic schema variants. 6. **Ward Methods**: It extracts custom validations registered as `_ward_methods` ([sigil.py:L971](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L971)). > [!NOTE] > **Unknown from inspected source**: > - How Contract metaclass class creation hooks (e.g. `__new__`) parse fields and facets, and trigger `build_sigil`. > - How the fields are initialized, how `cls._all_facets`, `cls._spec`, and `cls._ward_methods` are populated, or how the `_sigil` attribute is attached back to `cls`. > - How internal classes/facets like `NestedContractFacet`, `LazyContractFacet`, `Lens`, `Pipeline`, and `CastFault` are defined and function. --- FieldSpec API The [FieldSpec](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L63-L99) class uses `__slots__` optimization ([sigil.py:L66-L75](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L66-L75)) and exposes the following parameters via its constructor ([sigil.py:L77-L95](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L77-L95)): | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `name` | `str` | | The field name defined in the Contract schema. | | `facet` | `Any` | | The compiled field constraint constraints (e.g. a validation Facet). | | `required` | `bool` | | Denotes whether the field is required. | | `default` | `Any` | | Static default value when the field is omitted. | | `default_factory` | `Any` | | A callable factory returning dynamic default values. | | `pipeline` | `Pipeline \| None` | | Optional transformation pipeline of runes executed on the field value. | | `is_nested_contract` | `bool` | | True if the field points to a nested Contract. | | `is_lens` | `bool` | | True if the field is a Lens representation. | --- Sigil API The [Sigil](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L101-L500) class holds the compiled schema fields and options ([sigil.py:L104-L135](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L104-L135)): | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `fields` | `dict[str, FieldSpec]` | | Map of field names to their compiled specification. | | `ward_methods` | `tuple[Any, ...]` | | Ward vali

### Code Examples
```python
def validate(
    self,
    data: Any,
    *,
    strict: bool | None = None,
    partial: bool = False,
    context: dict[str, Any] | None = None,
) -> tuple[dict[str, list[str]], dict[str, Any]]

```

```python
@dataclass(frozen=True, slots=True)
class FieldDiff:
    was: str
    now: str
    breaking: bool

```

```python
@dataclass(frozen=True, slots=True)
class SigilDiff:
    added_fields: list[str]
    removed_fields: list[str]
    changed_fields: dict[str, FieldDiff]
    breaking: bool

```



---

## Framework Docs: docs/docs/contracts/field-annotations.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-field-annotations`

--- title: "Field Annotations & Computed Fields" description: "Annotation-driven validation styles and computed fields using @computed and Field()" icon: lucide/hash ---Aquilia Contracts provide a first-class, type-annotation-driven system that allows declaring schemas using standard Python type annotations. This system is entirely native to Aquilia, requiring no external validation libraries like Pydantic ([annotations.py:L4-6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L4-6)). --- Annotation-Driven Style vs Explicit Facets When defining contracts in Aquilia, you can use two main declaration styles: 1. **Annotation-Driven Style**: Fields are declared using standard Python type annotations alongside the [Field](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L111) descriptor or raw defaults ([annotations.py:L12-19](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L12-19)). 2. **Explicit Facet Style**: Fields are declared by instantiating Facet objects directly in the class namespace. Syntax Comparison --- ANNOTATION_TO_FACET Mapping The introspection engine utilizes the [ANNOTATION_TO_FACET](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L87) lookup dictionary to map Python type annotations to native Aquilia Facets ([annotations.py:L87-106](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L87-106)): | Python Type | Target Aquilia Facet Class | | :--- | :--- | | `str` | [TextFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L463-L540) | | `int` | [IntFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L626-L670) | | `float` | [FloatFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L673-L726) | | `bool` | [BoolFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L789-L811) | | `Decimal` | [DecimalFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L729-L783) | | `datetime` | [DateTimeFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L875-L903) | | `date` | [DateFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L817-L844) | | `time` | [TimeFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L847-L872) | | `timedelta` | [DurationFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L906-L947) | | `uuid.UUID` | [UUIDFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L950-L971) | | `dict` | [DictFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1176-L1258) | | `list` | [ListFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L977-L1040) | | `set` | [SetFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1043-L1107) | | `tuple` | [TupleFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1110-L1173) | | `bytes` | [TextFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L463-L540) | | `UploadFile` | [UploadFileFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1745-L1817) | | `FormData` | [FormDataFacet](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1820-L1866) | --- Field() Descriptor The [Field](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L111) descriptor class supplies metadata and constraints for annotation-driven fields ([annotations.py:L111-260](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/annotations.py#L111-260)). Parameters & Configuration | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `default` | `Any` | `UNSET` | Static default value for the field. | | `default_factory` | `Callable \| None` | `None` | A zero-argument callable that dynamically produces the default value. | | `required` | `bool \| None` | `None` | Explicit override to force or waive validation requirements. | | `read_only` | `bool` | `False` | When True, the field is output-only and excluded from incoming payloads. | | `write_only` | `bool` | `False` | When True, the field is input-only and excluded from serialized output. | | `allow_null` | `bool` | `False` | Allows the field to accept None as a valid input value. | | `allow_blank` | `bool` | `False` | Allows text fields to accept empty strings. | | `source` | `str \| None` | `None` | Path/key mapping override on the underlying model instance. | | `label` | `str \| None` | `None` | Human-readable label for documentation and UI. | | `help_text` | `str \| None` | `None` | Documentation helper string. | | `validators` | 

### Code Examples
```python
from aquilia.contracts import Contract, Field, computed
from aquilia.contracts.facets import TextFacet, IntFacet

# 1. Annotation-driven style
class UserContract(Contract):
    name: str = Field(min_length=2, max_length=100)
    age: int = Field(ge=0, le=150)
    role: str = "user"  # raw default value

# 2. Explicit facet style
class LegacyUserContract(Contract):
    name = TextFacet(min_length=2, max_length=100)
    age = IntFacet(min_value=0, max_value=150)
    role = TextFacet(default="user")

```

```python
class ProfileContract(Contract):
    first_name: str
    last_name: str

    @computed
    def display_name(self, instance) -> str:
        return f"{instance.first_name} {instance.last_name}"

```

```python
from decimal import Decimal
from uuid import UUID
from aquilia.contracts import Contract, Field, computed

class AddressContract(Contract):
    street: str
    city: str
    postal_code: str = Field(pattern=r"^\d{5}$")

class CompanyContract(Contract):
    # Scalar Mapping
    company_id: UUID
    name: str = Field(min_length=2, max_length=150)
    
    # Optional field (sets allow_null=True and required=False)
    description: str | None = None
    
    # Nested single and multiple contracts
    hq_address: AddressContract
    branches: list[AddressContract] = Field(default_factory=list)
    
    # Constrained Decimal
    annual_revenue: Decimal = Field(ge=0, max_digits=12, decimal_places=2)
    
    # Constrained choices
    status: str = Field(default="active", choices=["active", "inactive", "suspended"])

    @computed
    def is_enterprise(self, instance) -> bool:
        return instance.annual_revenue > Decimal("10000000.00")

```



---

## Framework Docs: docs/docs/contracts/projections.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-projections`

--- title: "Projections" description: "Declaring and using named subsets of fields for dynamic schema tailoring" icon: lucide/eye ---Projections allow you to declare and use named subsets of fields (facets) on a [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826-L2075), enabling dynamic tailoring of output schemas without duplicating contract definitions. --- 1. What is a Projection? A **Projection** is a named subset of facets, acting like a database view or a SQL `SELECT` projection over a model ([projections.py:L4-L6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L4-L6)). Instead of repeating lists of fields (e.g., `fields = [...]`) in different serializers or route definitions, projections let you define field lists once in the contract's specifications and select them dynamically by name at the route or controller level ([projections.py:L4-L6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L4-L6)). The concept is named "Projection" because it projects a subset of the model's facets onto the serialized output ([projections.py:L8-L11](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L8-L11)). --- 2. Defining Projections in `Spec.projections` Projections are declared within the `Spec` inner class of a [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826-L2075) class ([projections.py:L30-L38](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L30-L38)). The configurations are mapped via a dictionary: The dictionary maps the projection name (e.g., `"summary"`) to either: - A list/tuple of facet names ([projections.py:L88](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L88)). - Special reserve keywords like `"__all__"` or `"__minimal__"` ([projections.py:L41-L43](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L41-L43)). - A single field name string ([projections.py:L106-L107](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L106-L107)). --- 3. Special Values: `"__all__"` and `"__minimal__"` Aquilia supports two reserved values for projections: `"__all__"` Resolves to all non-write-only facets ([projections.py:L42](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L42)). During configuration, the registry resolves this by computing the set difference between all facet names and write-only facet names ([projections.py:L74](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L74), [projections.py:L83-L84](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L83-L84)). `"__minimal__"` Resolves to only the primary key (PK) and read-only facets ([projections.py:L43](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L43)). Inside the registry's configuration phase, it is mapped to a placeholder empty frozenset ([projections.py:L85-L87](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L85-L87)) and is fully resolved downstream by the [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826-L2075) class itself. --- 4. Exclusion Syntax: `"-field_name"` Prefix Instead of explicitly listing all fields to include, projections can define which fields to exclude by prefixing the facet name with a minus (`-`) sign ([projections.py:L45-L50](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L45-L50)). During configuration, the registry parses the fields: - Facets prefixed with a `"-"` are stripped of the prefix and added to an `excludes` list ([projections.py:L93-L94](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L93-L94)). - Other facets are added to an `includes` list ([projections.py:L95-L96](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L95-L96)). - If only exclusions are defined (`excludes and not includes`), the projection resolves to all available non-write-only facets minus the excluded ones ([projections.py:L98-L100](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L98-L100)). - If includes are specified (even if exclusion strings are in the raw list), the registry resolves the projection strictly to the `includes` list, ignoring the exclusions ([projections.py:L101-L102](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L101-L102)). - If the parsed fields list is empty, it defaults to all facets ([projections.py:L103-L104](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L103-L104)). --- 5. Default Projection: `Spec.default_projection` You can specify a defaul

### Code Examples
```python
class Spec:
    model = Product
    projections = {
        "summary": ["id", "name", "price"],
        "detail": ["id", "name", "description", "price", "category"],
        "admin": "__all__",
    }

```

```python
projections = {
    "public": ["-password", "-email"],  # projects all facets except password and email
}

```

```python
def configure(
    self,
    projections: dict[str, str | list[str]] | None,
    default: str | None,
    all_facet_names: set[str],
    write_only_names: set[str],
) -> None

```



---

## Framework Docs: docs/docs/contracts/ward.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-ward`

--- title: "Wards & Cross-Field Validation" description: "Cross-field validation using @ward decorators in Aquilia Contracts" icon: lucide/shield --- Wards are explicit cross-field validators in Aquilia Contracts that are registered during class-body evaluation. They replace older, fragile method-name prefix scanning with structured metadata and decorators. --- What is a Ward? A **Ward** is an explicit cross-field validator registered on an Aquilia [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826). As defined in [ward.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py), wards replace the legacy prefix-based scanning of `seal_*` or `async_seal_*` methods with an explicit decorator-driven registration system discovered once at class-body evaluation time (see [ward.py lines 2–6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L2-L6)). --- Bare Decorator Usage: `@ward` Using the decorator without arguments registers a synchronous ward method: Under the Hood * When used as a bare decorator `@ward`, the [ward](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L57) class intercepts the method call during class evaluation via its `__new__` method (see [ward.py lines 80–90](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L80-L90)). * It validates that the decorated object is indeed a callable (raising a `TypeError` if not). * It registers validation metadata on the function under `fn.__ward_meta__` as `{"mode": "sync", "name": fn.__name__}` (see [ward.py line 88](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L88)). --- Parameterised Factory: `@ward(mode="async")` When you need to perform validation that requires calling asynchronous APIs (such as checking a database or calling a remote service), you can parameterise the decorator: Under the Hood * Calling `@ward(mode="async")` invokes `__new__` without a decorated function, returning a new instance of the [ward](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L57) class acting as a decorator factory (see [ward.py lines 91–95](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L91-L95)). * The `mode` parameter is validated against the valid modes list, raising a `ValueError` if the specified mode is invalid. * When the returned `ward` instance is subsequently called with the decorated function (`fn`), its `__call__` method attaches the `__ward_meta__` dictionary using the stored mode (see [ward.py lines 105–110](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L105-L110)). --- The `WardMethod` Dataclass The metadata for each registered ward is stored in an instance of the [WardMethod](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L42-L47) class, a frozen, memory-optimized dataclass (using slots) defined in [ward.py lines 42–47](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L42-L47). | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `name` | `str` | | The name of the validator method. | | `fn` | `object` | | The actual validator callable/method object. | | `mode` | `str` | | The execution mode: either "sync" or "async". | --- Valid Validation Modes The validation engine supports a restricted set of modes defined in the internal constant `_VALID_MODES` (see [ward.py line 54](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L54)): * `"sync"`: Standard synchronous validation. * `"async"`: Asynchronous validation (requires an event loop to resolve). Any value passed to the decorator's `mode` parameter that is not in `_VALID_MODES` raises a `ValueError` during decoration (see [ward.py lines 81–82](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L81-L82)). --- Method Collection: `collect_ward_methods()` During Contract class creation, all registered wards are harvested using the [collect_ward_methods](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L118) helper function (see [ward.py lines 118–199](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L118-L199)). Inheritance and Override Semantics 1. **Inheritance Scan**: The function iterates through the base classes (`bases`) in Method Resolution Order (MRO) to collect inherited ward methods (see [ward.py lines 147–150](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L147-L150)). 2. **Namespace Scan**: It then scans the current class namespace for attributes decorated with `@ward` (identifiable by the `__ward_meta__` attribute) (see [ward.py lines 152–161](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L152-L161)). 3. **Override Mapping**: The inherited and own methods are merged. If a su

### Code Examples
```python
from aquilia.contracts import ward

class OrderContract(Contract):
    @ward
    def total_matches_items(self, data):
        computed = sum(i.price * i.qty for i in data.items)
        if abs(computed - data.total) > 0.01:
            self.reject("total", f"Expected {computed}, got {data.total}")

```

```python
class OrderContract(Contract):
    @ward(mode="async")
    async def discount_code_valid(self, data):
        if data.discount_code and not await lookup(data.discount_code):
            self.reject("discount_code", "Unknown code")

```

```python
DeprecationWarning: ClassName.method_name: seal_*/async_seal_* prefix convention is deprecated. Use @ward or @ward(mode='async') instead.
    
```



---

## Framework Docs: docs/docs/contracts/index.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-index`

--- title: "Contracts Overview" description: "Declaring models-to-world contracts in Aquilia" icon: lucide/layout --- Overview !!! info Evidence: `aquilia/contracts/__init__.py:4-7` An Aquilia Contract declares the data contract between a data model and the outside world. It specifies how incoming payloads are cast into Python types, verified for integrity (sealing), and persisted back (imprinting), as well as how outbound instances are mapped into dictionary representations (molding) for rendering. --- Core Concepts - **[Defining Contracts](defining-contracts.md)**: Creating classes inheriting from `Contract` with a nested `Spec` configuration class. - **[Facets](facets.md)**: Declaring field types and validation rules using built-in validators like `TextFacet`, `IntFacet`, `DateTimeFacet`, and `Computed`. - **[Field Annotations](field-annotations.md)**: Using type annotations with `Field()` and `@computed` for a clean, descriptor-driven coding style. - **[Projections](projections.md)**: Defining named subsets of fields (e.g., `"summary"`, `"detail"`) to serialize different shapes of the same contract. - **[Lenses](lenses.md)**: Mapping nested database relationships with built-in depth control, cycle prevention, and primary key fallback. - **[Wards & Cross-Field Validation](ward.md)**: Declaring multi-field validation constraints using the `@ward` decorator. - **[Lifecycle: Cast, Seal & Imprint](casting-sealing.md)**: Understanding how data moves through casting (type checking), sealing (integrity checks), and imprinting (saving). - **[Sigil & FieldSpec](sigil.md)**: Declaring low-level field spec templates and structural mapping rules. - **[Contract Unions](contract-union.md)**: Supporting discriminated unions and polymorphic API responses. - **[Integration Helpers](integration.md)**: Resolving and binding Contracts to HTTP requests and controller responses. - **[Schema Generation](schema-generation.md)**: Compiling Contracts into JSON Schema and OpenAPI schemas. - **[Contract Exceptions](exceptions.md)**: Troubleshooting cast, seal, imprint, projection, and lens failures.


---

## Framework Docs: docs/docs/contracts/schema-generation.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-schema-generation`

--- title: "Schema Generation" description: "Generating JSON Schema and OpenAPI schemas from Contracts" icon: lucide/file-json --- Aquilia provides built-in utilities to compile Contract definitions into standard OpenAPI and JSON Schema formats. This enables automated API documentation generation, client SDK generation, and request/response validation. The schema generation core resides in [aquilia/contracts/schema.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/schema.py). --- Functions `generate_schema()` The `generate_schema()` function generates a standard JSON Schema dictionary for a single Contract class. Under the hood, it delegates to the class method `to_schema()` on the Contract. Signature *(Defined in [schema.py:L19-37](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/schema.py#L19-L37))* Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `contract_cls` | `type[Contract]` | | The Contract class to generate the JSON Schema for. | | `projection` | `str \| None` | `None` | The name of the projection to use for filtering fields. If None, the default projection/full schema is used. | | `mode` | `"output" \| "input"` | `"output"` | Determines the context of the schema. Use "output" for serialization/response bodies and "input" for deserialization/request bodies. | Output Shape Returns a `dict[str, Any]` representing the compiled JSON Schema. For instance, a schema generated for `UserContract` with `mode="output"` will produce: --- `generate_component_schemas()` The `generate_component_schemas()` function generates OpenAPI-compliant component schemas for a collection of Contracts. It is designed to populate the `components.schemas` block of an OpenAPI document. Signature *(Defined in [schema.py:L39-68](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/schema.py#L39-L68))* Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `contract_classes` | `type[Contract]` | | A variable number of Contract classes to compile. | | `include_projections` | `bool` | `True` | If True, separate schemas will be generated for every projection defined on the Contract classes. | Output Shape Returns a nested dictionary `dict[str, dict[str, Any]]` mapping component names to their respective JSON Schema definitions. For each Contract class `bp_cls` passed as input, the function generates: 1. **Default Output Schema**: Registered under `bp_cls.__name__` (using `mode="output"`). 2. **Default Input Schema**: Registered under `f"{bp_cls.__name__}_Input"` (using `mode="input"`). 3. **Projection Schemas**: If `include_projections` is `True` and the Contract class has defined projections (e.g. `_projections.available` attribute), it creates a separate schema for each named projection (excluding the special `"__all__"` projection) under the key `f"{bp_cls.__name__}_{proj_name}"` (using `mode="output"`). !!! info The implementation ignores the special `"__all__"` projection name when iterating over available projections (see [schema.py:L63-64](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/schema.py#L63-L64)). --- Facet Schema Mapping Contract fields are represented by `Facet` objects. When compiling schemas, the engine calls the `to_schema()` method on each field's `Facet` class to convert it into its JSON Schema equivalent. Here is how the core facets map to JSON Schema types, mapped via their `to_schema()` definitions (compiled from [.cache/index_contracts.json](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/.cache/index_contracts.json)): | Facet / Class Name | Method Location | JSON Schema Representation | | :--- | :--- | :--- | | `Facet` | [facets.py:L396-409](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L396-L409) | Base class schema logic, sets common attributes like description, title, default values. | | `TextFacet` | [facets.py:L532-540](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L532-L540) | `{"type": "string"}` (optionally with `minLength`, `maxLength`, `pattern`). | | `EmailFacet` | [facets.py:L557-560](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L557-L560) | `{"type": "string", "format": "email"}`. | | `URLFacet` | [facets.py:L579-582](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L579-L582) | `{"type": "string", "format": "uri"}`. | | `SlugFacet` | [facets.py:L599-602](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L599-L602) | `{"type": "string", "format": "slug"}` (with slug character patterns). | | `IPFacet` | [facets.py:L617-620](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L617-L620) | `{"type": "string", "format": "ipv4"}` or `{"format": "ipv6"}`. | | `IntFacet` | [facets.py:L662-670](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts

### Code Examples
```python
def generate_schema(
    contract_cls: type[Contract],
    *,
    projection: str | None = None,
    mode: str = "output",
) -> dict[str, Any]:

```

```python
{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "email": { "type": "string", "format": "email" },
    "name": { "type": "string" }
  },
  "required": ["id", "email"]
}

```

```python
def generate_component_schemas(
    *contract_classes: type[Contract],
    include_projections: bool = True,
) -> dict[str, dict[str, Any]]:

```



---

## Framework Docs: docs/docs/contracts/defining-blueprints.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-defining-blueprints`

--- title: "Defining Contracts" description: "How to define schemas, specs, and lifecycles using Contracts" icon: lucide/pencil-ruler ---Aquilia Contracts are first-class framework primitives that declare and enforce strict contracts between your database models and the outside world. What is a Contract? A [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826) is NOT a serializer, but rather a **first-class framework primitive** [core.py:L8](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L8). It represents a unified contract between a Model and the outside world [core.py:L4](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L4). A [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826) defines the lifecycle of how data moves across the boundary of your application: - **Facets**: What data points are visible/writable [core.py:L833](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L833). - **Projections**: Named subsets of facets [core.py:L834](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L834). - **Seals**: Validation rules (field, cross-field, and async) [core.py:L835](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L835). - **Imprints**: How validated data is written back to the model [core.py:L836](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L836). --- Contract vs Serializer Based on the official implementation and documentation, Contracts differ from traditional serializers in the following key ways: - **Comprehensive Lifecycle Contract**: Traditional serializers typically focus on converting complex object graphs to and from primitive Python types. A Contract goes beyond serialization to define the complete model-world boundary: what the world sees (Facets), named subsets (Projections), how data enters (Casts), how integrity is enforced (Seals), and how data is written back (Imprints) [__init__.py:L4-7](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L4-L7). - **Persistence Ownership**: Serializers validate data but leave database operations to external handlers. In Aquilia, the Contract itself manages database persistence via `imprint` [core.py:L1310-1341](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L1310-L1341), which automatically distinguishes between model-writable fields and computed/constant facets to create or update database records [core.py:L1398-1429](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L1398-L1429). - **Composition and Slicing**: Contracts natively support union composition using the `|` operator [core.py:L630-644](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L630-L644) (producing a compiled [ContractUnion](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L676)) and projection-based slicing via subscript syntax [core.py:L609-624](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L609-L624). --- The Spec Inner Class To configure a Contract's settings without polluting its class namespace or colliding with database model configuration names, configurations are declared in an inner class named `Spec` [core.py:L163-164](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L163-L164). !!! warning Using the traditional name `Meta` instead of `Spec` raises a [ContractFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L25) during class construction [core.py:L305-309](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L305-L309). The metaclass parses this inner class into an internal [_SpecData](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L159) instance [core.py:L186-234](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L186-L234). The supported configuration fields are detailed below: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `model` | `ModelT \| None` | `None` | The associated model class to declare the contract for and derive facets from (core.py:L188, L206). | | `fields` | `list[str] \| str \| None` | `None` | Specifies which model fields to derive. Set to '__all__' to derive all model fields (core.py:L189, L207). | | `exclude` | `list[str] \| None` | `None` | Specifies derived model fields to exclude from the Contract (core.py:L190, L208). | | `read_only_fields` | `tuple[str, ...]` | `()` | Specifies fields that should be set to read-only (core.py:L191, L209). | | `write_only_fields` | `tuple[str, ...]` | `()` | Specifies fields that should be set to write-only (core.py:L192, L210). | | `extra_facets` | `dict[str, Facet]` | | | | `projections` | `dict[str, l

### Code Examples
```python
mermaid
graph TD
    Data[Raw Input Dict] --> Cast[1. Cast: Sigil Validation]
    Cast --> Seal[2. Seal: Wards & Hook Validation]
    Seal --> Imprint[3. Imprint: Persist to DB]

```

```python
mermaid
graph TD
    Instance[Model Instance] --> Access[Property: bp.data / to_dict]
    Access --> Filter[Filter: write_only facets & active projection]
    Filter --> Extract[Extract: facet.extract]
    Extract --> Mold[Mold: facet.mold / Lens depth check]
    Mold --> Output[Molded Primitive Dict]

```

```python
from aquilia.contracts import Contract, ward, IntFacet, TextFacet
from myapp.models import Article

class ArticleContract(Contract):
    class Spec:
        model = Article
        fields = ["title", "content", "category_id"]
        extra_fields = "reject"
        strict = True

    title = TextFacet(required=True, min_length=5)
    content = TextFacet(required=True)
    category_id = IntFacet(required=True)

    # Sync cross-field validator
    @ward
    def validate_content_length(self, data):
        if len(data.content) < len(data.title):
            self.reject("content", "Content must be longer than the title.")

    # Async validator (e.g., verifying category existence in database)
    @ward
    async def validate_category_exists(self, data):
        from myapp.models import Category
        exists = await Category.objects.filter(id=data.category_id).exists()
        if not exists:
            self.reject("category_id", "Selected category does not exist.")

# Execution Pipeline
async def create_article(payload: dict) -> Article:
    # 1. Cast
    bp = ArticleContract(data=payload)

    # 2. Seal
    # As the contract has async wards, we must call is_sealed_async()
    if not await bp.is_sealed_async():
        raise ValueError(f"Validation errors: {bp.errors}")

    # 3. Imprint
    article = await bp.imprint()
    return article

```



---

## Framework Docs: docs/docs/contracts/api-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-contracts-api-reference`

--- title: "Contracts API Reference" description: "Complete API reference for the Aquilia Contracts module" icon: lucide/database --- Overview This is the comprehensive API reference for the `aquilia.contracts` package. It details every class, function, decorator, and constant exported in the module's public interface, linking each back to its source code implementation. --- 1. Core Classes & Schemas [Contract](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826-L2075) - **Summary**: The core contract definition class mapping model data to the outside world. - **Evidence Citation**: `aquilia/contracts/core.py:826-2075` - **Class Signature**: - **Initializer Signature**: - **Parameters**: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `instance` | `ModelT \| list[ModelT] \| None` | `None` | Model instance for outbound (mold) operations. | | `data` | `Any` | `UNSET` | Raw input data for inbound (cast + seal) operations. | | `many` | `bool` | `False` | If True, expect a list of instances or input data. | | `partial` | `bool` | `False` | If True, bypass required check constraints (PATCH semantics). | | `projection` | `str \| None` | `None` | Named projection subset of fields to serialize/deserialize. | | `context` | `dict[str, Any] \| None` | `None` | Context dictionary containing request container or other DI objects. | - **Return Type**: `Contract` - **Raises**: - [CastFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L62-L79): When input values cannot be cast to target facet types. - [SealFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L82-L108): When field or cross-field validation rules fail. - [ProjectionFault](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/exceptions.py#L117-L126): When an unknown projection name is requested. --- [ContractMeta](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L239-L644) - **Summary**: Metaclass for Contract classes handling Spec parsing, Facet collection, and model field derivation. - **Evidence Citation**: `aquilia/contracts/core.py:239-644` - **Signature**: - **Parameters**: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `name` | `str` | `(None)` | Name of the class. | | `bases` | `tuple[type, ...]` | `(None)` | Base classes of the new Contract class. | | `namespace` | `dict[str, Any]` | `(None)` | Class attributes and methods namespace dict. | - **Return Type**: `ContractMeta` - **Raises**: None. --- [ward](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L57-L110) - **Summary**: Decorator/decorator-factory for registering cross-field validator methods on a Contract. - **Evidence Citation**: `aquilia/contracts/ward.py:57-110` - **Signature**: - **Parameters**: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `fn` | `Callable[..., Any] \| None` | `None` | The validation function to decorate. | | `mode` | `str` | `"sync"` | Execution mode. Must be "sync" or "async". | - **Return Type**: `Callable[..., Any] | ward` - **Raises**: - `ValueError`: If the mode is not `"sync"` or `"async"`. - `TypeError`: If the decorated object is not a callable. --- [WardMethod](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/ward.py#L42-L47) - **Summary**: Dataclass descriptor representing a registered cross-field validator. - **Evidence Citation**: `aquilia/contracts/ward.py:42-47` - **Signature**: - **Parameters**: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `name` | `str` | `(None)` | Method name. | | `fn` | `object` | `(None)` | The validator method callable. | | `mode` | `str` | `(None)` | Validation mode ("sync" or "async"). | - **Return Type**: `WardMethod` - **Raises**: None. --- [Sigil](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/sigil.py#L101-L498) - **Summary**: Immutable compiled representation of a Contract's validation schema. - **Evidence Citation**: `aquilia/contracts/sigil.py:101-498` - **Signature**: - **Parameters**: | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `fields` | `dict[str, FieldSpec]` | `(None)` | Compiled specifications for all fields in the schema. | | `ward_methods` | `tuple[Any, ...]` | `(None)` | Tuple of compiled cross-field validator methods. | | `strict` | `bool` | `False` | If True, extra keys in input payloads will trigger validation failures. | | `revision` | `int \| None` | `None` | Schema revision number for data migrations. | | `migrate_from` | `dict[int, Callable[[dict], dict]] \| None` | `None` | Dictionary mapping old revision numbers to migration hooks. | | `migrate_step` | `Callable[[dict, int], dict] \| None` | `None` | Dynamic step-based migration hook. | | `discriminator` | `str \| None` | `None` | Polymorphic discriminator field name for unions. | - **Return Type**: `

### Code Examples
```python
class Contract(Generic[ModelT], metaclass=ContractMeta)
  
```

```python
def __init__(
      self,
      instance: ModelT | list[ModelT] | None = None,
      *,
      data: Any = UNSET,
      many: bool = False,
      partial: bool = False,
      projection: str | None = None,
      context: dict[str, Any] | None = None,
  )
  
```

```python
class ContractMeta(type)
  
```



---

## Framework Docs: docs/docs/controller/versioning.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-versioning`

--- title: "Versioning" description: "API versioning at the controller and route levels in Aquilia" icon: lucide/git-branch ---Aquilia provides a flexible, declarative routing and API versioning system. Versioning can be defined globally at the controller level or overridden at the individual route level. Under the hood, version bindings are extracted during compile-time/registration and stored directly on controller method functions as metadata. This guide covers how versioning is implemented and configured in Aquilia. --- Controller-Level Versioning At the controller level, versioning is defined by setting the `version` class attribute. As defined in [`aquilia/controller/base.py`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L556): When you specify `version` on a subclass of [`Controller`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L497), it establishes the default API version for all routes defined in that controller. For example, see [`aquilia/controller/base.py` line 532-538](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L532-L538): --- Route-Level Versioning Individual route decorators allow you to override or extend the controller's default version using the `version` parameter. In [`aquilia/controller/decorators.py` line 64](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L64), the base class [`RouteDecorator`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L30) supports a `version` parameter in its constructor: This parameter is saved as an instance attribute (`self.version`) at [`aquilia/controller/decorators.py` line 122](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L122): All standard HTTP decorators inherit this parameter, including: - [`GET`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L180) (line 204) - [`POST`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L230) (line 254) - [`PUT`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L280) (line 304) - [`PATCH`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L330) (line 354) - [`DELETE`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L380) (line 404) - [`route`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L630) (line 651) Setting `version` on a route decorator overrides the controller-level `version` attribute for that specific route (see [`aquilia/controller/decorators.py` lines 98-101](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L98-L101)). --- Metadata Storage: `__version_metadata__` When a controller method is decorated with a route decorator, metadata is extracted and stored directly on the decorated function. First, standard route metadata is collected into a `metadata` dictionary and appended to the function's `__route_metadata__` list. This includes storing the version at [`aquilia/controller/decorators.py` line 162](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L162): Second, if `version` is specified, the decorator attaches or updates the [`__version_metadata__`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L168-L175) attribute on the function. This attribute is used during server registration. As shown in [`aquilia/controller/decorators.py` lines 168-175](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L168-L175): The system initializes [`__version_metadata__`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L168-L175) as a dictionary containing a `"versions"` key mapped to a list of version strings. --- List vs Single Version Binding Aquilia supports binding routes to either a single version or multiple versions simultaneously: 1. **Single Version**: You can pass a string (e.g., `version="1.0"`). 2. **Multiple Versions**: You can pass a list of strings (e.g., `version=["1.0", "2.0"]`). The decorator normalizes the input into a list of strings when saving to [`__version_metadata__`](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L168-L175) (see [`aquilia/controller/decorators.py` line 171](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/decorators.py#L171)): This allows a single handler method to handle requests across multiple distinct API versions without repeating the route decoration. --- Deduplication and Order Preservation Aquilia prevents double decoration and metadata pollution through two levels of deduplication: 1. Route Metadata Deduplication To prevent the same route (matching HTTP method and URL path) from being added multiple t

### Code Examples
```python
class Controller(metaclass=_ControllerMeta):
    # ...
    version: str | None = None  # API version: "v1", "v2", etc.

```

```python
class UsersController(Controller):
    prefix = "/users"
    version = "v1"
    # ...

```

```python
class RouteDecorator:
    def __init__(
        self,
        path: str | None = None,
        *,
        # ...
        # ── API Versioning ───────────────────────────────────────────
        version: str | list[str] | None = None,
    ):

```



---

## Framework Docs: docs/docs/controller/throttle.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-throttle`

--- title: "Throttle & Rate Limiting" description: "Rate limiting with Throttle" icon: lucide/timer ---Purpose The `Throttle` class provides a **sliding-window in-memory rate limiter** for Aquilia controllers (lines 379-481). It tracks request timestamps per client and enforces configurable rate limits to protect against abuse and ensure fair resource allocation. **Key characteristics:** - **Sliding window algorithm**: Tracks actual request timestamps, not fixed time buckets - **In-memory storage**: Fast but ephemeral (resets on application restart) - **Per-client isolation**: Uses client IP addresses to identify distinct clients - **Automatic cleanup**: Prevents memory leaks through periodic cleanup and LRU eviction Evidence: Class docstring at lines 379-390. Constructor **Parameters:** - **`limit`** (int, default: 100): Maximum number of requests allowed within the time window - **`window`** (int, default: 60): Time window in seconds for rate limiting - **`max_clients`** (int, default: 10000): Maximum number of clients to track before evicting oldest entries **Defaults:** 100 requests per 60 seconds, tracking up to 10,000 unique clients. Evidence: Constructor signature at lines 392-397. `check()` Method Validates whether a request is within the rate limit. **Return contract:** - Returns `True` if the request is **allowed** (within limit) - Returns `False` if the request is **throttled** (limit exceeded) **Side effects:** - Records the current timestamp for allowed requests - Triggers periodic cleanup when `window` seconds have elapsed since last cleanup - Evicts the oldest client when `max_clients` limit is reached (LRU eviction) - Prunes expired timestamps for the current client Evidence: Method signature and behavior at lines 414-441, with SEC-CTRL-04 security note at lines 419-422. Client Identification `_client_key()` Method Extracts a unique client identifier from the request (lines 399-412). **Resolution strategy:** 1. **First**: Calls `request.client_ip()` if available — respects trusted proxy chain validation 2. **Fallback**: Extracts direct client IP from ASGI scope `client` tuple 3. **Last resort**: Returns `"unknown"` **Security note:** Never trusts `X-Forwarded-For` headers directly; relies on Aquilia's validated `client_ip()` method to handle proxy chains correctly. Evidence: Implementation at lines 399-412 with inline comments about trusted-proxy validation. Memory Management The `Throttle` class implements two memory protection mechanisms to prevent unbounded growth: Periodic Cleanup Removes all clients whose request timestamps have fully expired (lines 443-447). Triggered automatically during `check()` when `window` seconds have elapsed since the last cleanup (lines 428-430). **Logic:** Deletes clients where the most recent timestamp is older than `now - window`. Evidence: Method at lines 443-447, invoked at lines 428-430. LRU Eviction Evicts the client with the oldest last-access time when `max_clients` limit is reached (lines 449-461). **Trigger:** Automatically called in `check()` when adding a new client would exceed `max_clients` (lines 432-434). **Algorithm:** Iterates through all tracked clients, finds the one with the oldest most-recent timestamp, and removes it. Evidence: Method at lines 449-461, invoked at lines 432-434 with SEC-CTRL-04 security annotation. `retry_after` Property Returns the number of seconds until the rate limit window resets (lines 463-465). **Return value:** The configured `window` value (approximate reset time). **Use case:** Can be used to populate the `Retry-After` HTTP header in 429 (Too Many Requests) responses. Evidence: Property definition at lines 463-465. `reset()` Method Clears all rate limit state by emptying the internal `_requests` dictionary (lines 467-469). **Use cases:** - Testing and development - Administrative reset operations - Graceful state clearing Evidence: Method at lines 467-469. Controller-Level Usage Apply rate limiting to **all routes** in a controller by setting the `throttle` class attribute: Both `/users` and `/users/:id` will enforce the 100 req/60s limit per client. Evidence: Class attribute `throttle` at line 583, example usage in docstring at lines 387-390. Route-Level Override Override controller-level throttling for **specific routes** by passing a `throttle` parameter to the route decorator: The `/users/search` endpoint has a stricter limit than other routes. Evidence: Route-level throttle parameter mentioned in docstring at lines 388-390. Code Examples Basic Rate Limiting Per-Route Customization High-Capacity Throttle Manual Throttle Check You can also check throttle state manually in handler logic: --- **Evidence Summary:** - Class definition: lines 379-481 - Constructor: lines 392-397 - `check()` method: lines 414-441 - `_client_key()`: lines 399-412 - Cleanup methods: lines 443-461 - Properties and reset: lines 463-469 - Controller integration: line 583 (class attribute) - Usage examples: docstrings at lines 379-390 A

### Code Examples
```python
Throttle(limit: int = 100, window: int = 60, max_clients: int = 10000)

```

```python
def check(self, request: Any) -> bool

```

```python
def _client_key(self, request: Any) -> str

```



---

## Framework Docs: docs/docs/controller/validation.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-validation`

--- title: "Validation" description: "Request validation" icon: lucide/check-square ---Controller-layer request body validation via Aquilia Contracts. validate_body() Signature The `validate_body()` decorator parses and validates request bodies through Contract classes. On success, it injects the validated `body: dict` as a keyword argument to the handler. On failure, it returns HTTP 422 Unprocessable Entity with structured errors. **Source:** Lines 47-53 Parameters - **contract_class** (`type`): The Contract class to validate against - **projection** (`str`, optional): Contract projection to use for allowed fields. Defaults to `"__all__"` Behavior The decorator handles multiple content types (lines 58-76): - **application/json**: Parses JSON body - **multipart/form-data**: Parses multipart form data - **application/x-www-form-urlencoded**: Parses URL-encoded forms - **Fallback**: Attempts JSON parsing, then form parsing On validation success, the handler receives `body` as a keyword argument containing the validated data (line 108). ValidationFault Base fault class for all validation-related faults. Uses the custom `VALIDATION_DOMAIN` fault domain (line 22). **Source:** Lines 25-27 - **Domain**: `FaultDomain.custom("validation", "Request body validation faults")` (line 22) - **Severity**: `Severity.WARN` RequestBodyValidationFault Raised when request body fails Contract validation. **Source:** Lines 30-32 - **Code**: `"validation.body_invalid"` - **Message**: `"Request body failed Contract validation"` - **HTTP Status**: 422 Unprocessable Entity (line 97) When validation fails, the response includes (lines 94-97): - `error`: Fault message - `code`: Fault code - `detail`: Detailed validation errors from Contract RequestBodyParseFault Raised when request body cannot be parsed. **Source:** Lines 35-37 - **Code**: `"validation.body_parse_error"` - **Message**: `"Request body could not be parsed"` - **HTTP Status**: 400 Bad Request (line 80) Contract Integration The validator integrates with Aquilia Contracts through the following mechanism (lines 84-107): 1. **Instantiation**: Creates a Contract instance with the parsed data and projection (line 84) 2. **Validation**: Calls `is_sealed_async()` if available, otherwise `is_sealed()` (lines 85-88) 3. **Error Collection**: Retrieves validation errors via `errors` attribute or `seal_errors()` method (lines 90-91) 4. **Data Extraction**: Uses `validated_data` attribute if available (line 106) Async Support The decorator supports both synchronous and asynchronous Contract validation (lines 85-88): Code Examples Basic Usage **Source Example:** Lines 5-17 (module docstring) With Custom Projection Error Response Format When validation fails (lines 94-97), the response structure is: When parsing fails (lines 78-81), the response structure is: Content Type Handling The decorator automatically handles different content types (lines 58-76): All content types are parsed and passed to the Contract for validation.

### Code Examples
```python
def validate_body(contract_class: type, *, projection: str = "__all__") -> Any:
    """
    Decorator: parse + validate the request body through a Contract.

    On success:  injects ``body: dict`` as the first extra keyword argument.
    On failure:  returns HTTP 422 Unprocessable Entity with structured errors.

    Args:
        contract_class: The Contract class to validate against.
        projection:      Contract projection to use for allowed fields.
    """

```

```python
class ValidationFault(Fault):
    domain = VALIDATION_DOMAIN
    severity = Severity.WARN

```

```python
class RequestBodyValidationFault(ValidationFault):
    code = "validation.body_invalid"
    message = "Request body failed Contract validation"

```



---

## Framework Docs: docs/docs/controller/lifecycle-hooks.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-lifecycle-hooks`

--- title: "Lifecycle Hooks" description: "Understanding and hook-in to the Aquilia Controller execution lifecycle" icon: lucide/activity --- Overview Aquilia controllers provide hook methods that allow you to execute logic at key points in the application and request lifecycle. These hooks support database connections, logging, custom validations, and response manipulations. --- Startup & Shutdown Hooks !!! info Evidence: `aquilia/controller/base.py:615-629` These hooks are executed when the controller itself starts up or shuts down. on_startup [on_startup](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L615-L621) is called when the controller is initialized. > [!NOTE] > This hook is executed **only in singleton instantiation mode**. - **Signature**: `async def on_startup(self, ctx: RequestCtx) -> None` - **Use Case**: One-time setup operations, such as establishing persistent database pools or opening HTTP client sessions. on_shutdown [on_shutdown](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L623-L629) is called when the controller is destroyed. > [!NOTE] > This hook is executed **only in singleton instantiation mode**. - **Signature**: `async def on_shutdown(self, ctx: RequestCtx) -> None` - **Use Case**: Cleanup operations, such as closing database connection pools or terminating background tasks. --- Request & Response Hooks !!! info Evidence: `aquilia/controller/base.py:631-652` These hooks execute on every HTTP request processed by the controller's route handlers. on_request [on_request](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L631-L637) is called immediately before the matched handler method is executed. - **Signature**: `async def on_request(self, ctx: RequestCtx) -> None` - **Use Case**: Setting request-scoped parameters in `ctx.state`, logging request entry, or executing controller-wide preprocessing. on_response [on_response](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L639-L652) is called after the handler method has successfully executed and returned a `Response` object. - **Signature**: `async def on_response(self, ctx: RequestCtx, response: "Response") -> "Response"` - **Use Case**: Modifying headers (e.g., adding caching headers or security headers), logging execution time, or transforming response payloads. --- Code Example

### Code Examples
```python
import time
from aquilia import Controller, GET, RequestCtx, Response

class LifecycleDemoController(Controller):
    prefix = "/lifecycle"
    instantiation_mode = "singleton"

    async def on_startup(self, ctx: RequestCtx) -> None:
        # Initialize resources
        self.start_time = time.time()

    async def on_shutdown(self, ctx: RequestCtx) -> None:
        # Cleanup resources
        pass

    async def on_request(self, ctx: RequestCtx) -> None:
        # Track start time of the request
        ctx.state["start_time"] = time.perf_counter()

    async def on_response(self, ctx: RequestCtx, response: Response) -> Response:
        # Calculate request execution duration and append header
        duration = time.perf_counter() - ctx.state["start_time"]
        response.headers["X-Process-Time"] = f"{duration:.4f}s"
        return response

    @GET("/ping")
    async def ping(self, ctx: RequestCtx) -> dict:
        return {"message": "pong"}

```



---

## Framework Docs: docs/docs/controller/instantiation-modes.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-instantiation-modes`

--- title: "Instantiation Modes" description: "Understanding Controller lifecycles and instantiation modes in Aquilia" icon: lucide/cpu ---Aquilia controllers support two distinct instantiation modes that govern their lifecycle, memory footprint, and dependency resolution. These modes are managed by [ControllerFactory](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L24) during application runtime. --- The InstantiationMode Enum The [InstantiationMode](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L17) enum (defined in [aquilia/controller/factory.py:L17-L21](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L17-L21)) determines the lifecycle behavior of a controller: - **`PER_REQUEST`** ([factory.py:L20](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L20)): A new instance of the controller is created for each incoming request. - **`SINGLETON`** ([factory.py:L21](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L21)): A single instance of the controller is created once, cached, and shared across all requests. --- ControllerFactory.create Method Signature The factory instantiates controllers using the asynchronous [ControllerFactory.create()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L43) method (defined in [aquilia/controller/factory.py:L43-L72](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L43-L72)): Parameter Details | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `controller_class` | `type` | | The controller class type to be instantiated. | | `mode` | `InstantiationMode` | `InstantiationMode.PER_REQUEST` | Governs whether the factory retrieves a cached instance or constructs a new one. | | `request_container` | `Any \| None` | `None` | The request-scoped Dependency Injection container. | | `ctx` | `Any \| None` | `None` | The request context used during instantiation or lifecycle hook invocation. | --- Singleton Caching Mechanism When the controller is configured as a `SINGLETON`, the factory implements a caching mechanism within [ControllerFactory._create_singleton()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L74) (defined in [aquilia/controller/factory.py:L74-L102](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L74-L102)): 1. **Cache Lookup**: Before instantiating, the factory checks if the controller already exists in the `self._singletons` registry ([factory.py:L80-L81](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L80-L81)): 2. **Scope Validation**: It performs validation to ensure the controller does not violate scope boundary rules ([factory.py:L84](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L84)). 3. **DI Resolution and Instantiation**: It resolves dependencies from the global application container (`self.app_container`) using [ControllerFactory._resolve_and_instantiate()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L126) and instantiates the controller ([factory.py:L87-L90](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L87-L90)). 4. **Hook Execution**: It executes the startup hook (see below) and stores the instance in the cache registry ([factory.py:L101](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L101)). --- Startup and Shutdown Hooks Startup Hook For controllers running in `SINGLETON` mode, [ControllerFactory._create_singleton()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L74) ensures that the `on_startup` hook is executed exactly once ([factory.py:L93-L99](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L93-L99)): !!! warning The `on_startup` hook is **only** executed for singletons during their first instantiation. For per-request controllers, the factory does not invoke lifecycle hooks because the controller engine handles request/response hooks directly to avoid double invocation ([factory.py:L113-L114](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L113-L114)): Shutdown Hook During application shutdown, [ControllerFactory.shutdown()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L309) cleans up all singleton instances by invoking their `on_shutdown` hook ([aquilia/controller/factory.py:L309-L322](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L309-L322)): --- Dependency Injection and Constructor Resolution To minimize performance overhead associated with run-time reflection (`inspect.signature` and `typing.get_type_hints`), the factory caches analyzed constructor parameters. Constructor R

### Code Examples
```python
class InstantiationMode(str, Enum):
    PER_REQUEST = "per_request"
    SINGLETON = "singleton"

```

```python
async def create(
    self,
    controller_class: type,
    mode: InstantiationMode = InstantiationMode.PER_REQUEST,
    request_container: Any | None = None,
    ctx: Any | None = None,
) -> Any:

```

```python
if controller_class in self._singletons:
       return self._singletons[controller_class]
   
```



---

## Framework Docs: docs/docs/controller/pagination.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-pagination`

--- title: "Pagination" description: "Pagination strategies" icon: lucide/list-ordered ---Overview Aquilia provides three built-in pagination strategies for handling large datasets efficiently (lines 1-13): - **PageNumberPagination** — Classic page-based navigation using `?page=2&page_size=20` - **LimitOffsetPagination** — SQL-style pagination using `?limit=20&offset=40` - **CursorPagination** — Keyset-based pagination using opaque cursor tokens `?cursor=<opaque>` for constant-time page jumps All pagination backends work seamlessly with both ORM QuerySets and plain Python lists (line 14). Each paginator implements query optimization for ORM queries, using `.count()` and `.offset().limit()` to avoid fetching entire datasets into memory. PageNumberPagination Classic page-number pagination that's intuitive for users and easy to bookmark (lines 166-301). Query Parameters - `page` — Page number (default: 1) - `page_size` — Items per page (default: 20) Configuration **Lines 182-186**: Default configuration attributes. You can customize these at the class level or via constructor: Response Envelope **Lines 169-181**: PageNumberPagination returns a comprehensive response envelope: - `count` — Total number of items across all pages - `total_pages` — Total number of pages - `page` — Current page number - `page_size` — Items per page - `next` / `previous` — Fully-qualified URLs for navigation (null if unavailable) - `results` — Array of items for the current page QuerySet Optimization **Lines 253-301**: For ORM QuerySets, PageNumberPagination uses optimized queries instead of loading all records: This avoids loading 1,000,000 records just to return 20 items. LimitOffsetPagination SQL-style pagination using limit and offset parameters (lines 304-414). Query Parameters - `limit` — Maximum items to return (default: 20) - `offset` — Number of items to skip (default: 0) Configuration **Lines 319-323**: Configure defaults at the class level or via constructor. Response Envelope **Lines 307-318**: Returns a simpler envelope without page numbers: **Lines 345-376**: Navigation links adjust offset automatically: - `next` — Advances offset by `limit` (offset 40 → 60) - `previous` — Moves back by `limit`, clamped to 0 (offset 40 → 20) QuerySet Optimization **Lines 378-414**: Like PageNumberPagination, uses `.count()` and `.offset().limit()` for efficient ORM pagination. CursorPagination Cursor-based (keyset) pagination for very large datasets with constant-time page jumps regardless of size (lines 417-633). Query Parameters - `cursor` — Opaque base64-encoded token pointing to the last item's ordering key - `page_size` — Items per page (default: 20) Configuration **Lines 447-452**: The `ordering` field determines which column is used for keyset navigation. Use `-` prefix for descending order. Response Envelope **Lines 429-437**: Returns only navigation links and results (no count, since that would require scanning the entire table): Cursor Generation and Security **Lines 459-499**: Cursors are HMAC-SHA256 signed to prevent tampering: Cursor format: `<base64-payload>.<base64-signature>` **Lines 463-477**: The HMAC secret is sourced from `AQUILIA_CURSOR_SECRET` environment variable. If not set, an ephemeral per-process key is generated (cursors won't survive restarts): **Set `AQUILIA_CURSOR_SECRET` in production** for cursor stability across deployments. Keyset Mechanics **Lines 558-615**: CursorPagination uses WHERE clauses on the ordering field instead of OFFSET, enabling constant-time pagination: This means page 1000 is just as fast as page 1, unlike OFFSET-based pagination which scans and skips rows. NoPagination **Lines 148-157**: Passthrough pagination that returns all results in a standard envelope: Useful for small datasets or when you want consistent response envelopes without actual pagination. Declarative Usage The recommended way to enable pagination is via the `pagination_class` parameter on route decorators (lines 16-24): When `pagination_class` is set: 1. The framework detects if the handler returns a QuerySet or list 2. Calls `paginator.paginate_queryset()` (async) or `paginator.paginate_list()` automatically 3. Returns the paginated envelope as JSON You can also use custom pagination instances: Explicit Usage For fine-grained control, instantiate a paginator and call `.paginate_list()` or `.paginate_queryset()` manually (lines 26-29): **Lines 115-126** (BasePagination interface): - `.paginate_list(data: list, request)` → Paginate in-memory lists - `.paginate_queryset(queryset, request)` → Paginate ORM QuerySets (async) QuerySet vs List Support **Lines 127-141**: All paginators implement both `paginate_list` and `paginate_queryset`: - **List support**: All paginators work with plain Python lists immediately - **QuerySet support**: PageNumberPagination, LimitOffsetPagination, and CursorPagination override `paginate_queryset()` with optimized queries - **Serialization**: Models with `.to_dict()` are automatically conve

### Code Examples
```python
class PageNumberPagination(BasePagination):
    page_size: int = 20              # Default items per page
    max_page_size: int = 1000        # Maximum allowed page size
    page_param: str = "page"         # Query param name for page number
    page_size_param: str = "page_size"  # Query param name for page size

```

```python
# Custom pagination class
class LargePagePagination(PageNumberPagination):
    page_size = 100
    max_page_size = 500

# Or instantiate with custom values
paginator = PageNumberPagination(page_size=50, max_page_size=200)

```

```python
{
    "count": 1200,
    "total_pages": 60,
    "page": 2,
    "page_size": 20,
    "next": "http://host/items/?page=3&page_size=20",
    "previous": "http://host/items/?page=1&page_size=20",
    "results": [...]
}

```



---

## Framework Docs: docs/docs/controller/index.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-index`

--- title: "Controller Module Overview" description: "Overview of class-based Controller architecture in Aquilia" icon: lucide/layers --- Overview !!! info Evidence: `aquilia/controller/__init__.py:4-12` The Aquilia Controller system provides a class-based architecture for request handling, replacing traditional function-based `@flow` handlers. Key Features - **Manifest-first**: Controllers are registered and declared in the module manifest (`module.aq`). - **DI-first**: Supports dependency injection in both constructors (`__init__`) and handler methods. - **Pipeline-first**: Middleware and request processing pipelines can be declared at both the class level and method level. - **Static-first**: Metadata is parsed and extracted at compile time rather than at import time or request time. - **Zero import-time side effects**: Importing controller files does not execute routing or setup side effects. --- Module Structure The controller system consists of several components: - **[Defining Controllers](defining-controllers.md)**: Inheriting from `Controller` and using configuration attributes. - **[Request Context](request-context.md)**: Utilizing the `RequestCtx` object to access parameters, body data, and request state. - **[HTTP Decorators](http-decorators.md)**: Decorating handler methods using HTTP verb decorators (`@GET`, `@POST`, `@PUT`, `@DELETE`, etc.). - **[Lifecycle Hooks](lifecycle-hooks.md)**: Injecting logic into controller initialization (`on_startup`, `on_shutdown`) and request processing (`on_request`, `on_response`). - **[Instantiation Modes](instantiation-modes.md)**: Managing lifecycle lifespans (singleton vs per-request). - **[Exception Filters](exception-filters.md)**: Catching and normalizing errors via `ExceptionFilter`. - **[Interceptors](interceptors.md)**: Wrapping request handling with before/after logic. - **[Throttle](throttle.md)**: Applying sliding-window rate limiting. - **[Pagination](pagination.md)**: Configuring pagination strategies. - **[Filtering](filtering.md)**: Performing list search, ordering, and field-based filtering. - **[Content Negotiation](renderers.md)**: Format-aware response rendering. - **[Validation](validation.md)**: Validating request body data using `validate_body`. - **[OpenAPI Docs](openapi.md)**: Generating interactive Swagger UI and ReDoc pages. - **[Versioning](versioning.md)**: Route-level and class-level API versioning.


---

## Framework Docs: docs/docs/controller/defining-controllers.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-defining-controllers`

--- title: "Defining Controllers" description: "How to define and configure Aquilia Controller classes" icon: lucide/code-2 --- Overview Controllers are class-based request handlers in Aquilia that provide a structured approach to building APIs. !!! info 📎 aquilia/controller/base.py:497-662 Controllers support: - Constructor dependency injection - Method-level route definitions with decorators - Class-level and method-level pipelines - Lifecycle hooks for startup, shutdown, request, and response processing - Template rendering support - API versioning - Rate limiting (throttle) - Interceptors (before/after handler hooks) - Exception filters (structured error handling) - Handler execution timeouts !!! info 📎 aquilia/controller/base.py:503-550 Minimal Controller Example The simplest controller inherits from `Controller` and defines routes using HTTP method decorators: !!! info 📎 aquilia/controller/base.py:497 The `prefix` attribute defines the base URL path for all routes in the controller. !!! info 📎 aquilia/controller/base.py:525 Class-Level Configuration Controllers support extensive class-level configuration through attributes: prefix URL prefix prepended to all routes in the controller. !!! info 📎 aquilia/controller/base.py:525 pipeline List of pipeline nodes applied to all methods in the controller. !!! info 📎 aquilia/controller/base.py:526 Pipelines enable authentication, authorization, validation, and other cross-cutting concerns. tags OpenAPI tags for documentation and API organization. !!! info 📎 aquilia/controller/base.py:527 instantiation_mode Controls controller lifecycle: `"per_request"` (default) or `"singleton"`. !!! info 📎 aquilia/controller/base.py:528 - `"per_request"`: New instance created for each request - `"singleton"`: Single instance shared across all requests version API version string for versioned APIs. !!! info 📎 aquilia/controller/base.py:531 throttle Rate limiting configuration using the `Throttle` class. !!! info 📎 aquilia/controller/base.py:532 The throttle instance implements sliding-window rate limiting. !!! info 📎 aquilia/controller/base.py:355-460 Throttle constructor accepts: - `limit`: Maximum number of requests - `window`: Time window in seconds - `max_clients`: Maximum tracked clients (default 10000) !!! info 📎 aquilia/controller/base.py:370-375 interceptors List of `Interceptor` instances that wrap handler execution with before/after logic. !!! info 📎 aquilia/controller/base.py:533 Interceptors support cross-cutting concerns like logging, caching, timing, and response transformation. !!! info 📎 aquilia/controller/base.py:303-347 exception_filters List of `ExceptionFilter` instances that handle exceptions from controller handlers. !!! info 📎 aquilia/controller/base.py:534 Exception filters convert unhandled exceptions into proper HTTP responses. !!! info 📎 aquilia/controller/base.py:260-295 timeout Handler execution timeout in seconds. Set to `0` to disable (default). !!! info 📎 aquilia/controller/base.py:535 max_body_size Maximum request body size in bytes. Set to `0` to disable (default). !!! info 📎 aquilia/controller/base.py:536 Lifecycle Hooks Controllers provide four lifecycle hooks for initialization and request/response processing: on_startup Called when the controller is initialized (singleton mode only). !!! info 📎 aquilia/controller/base.py:615-621 **Signature:** Use for one-time initialization like opening database connections. on_shutdown Called when the controller is destroyed (singleton mode only). !!! info 📎 aquilia/controller/base.py:623-629 **Signature:** Use for cleanup like closing connections. on_request Called before each request is processed. !!! info 📎 aquilia/controller/base.py:631-637 **Signature:** Use for per-request initialization or validation. on_response Called after each request is processed, allowing response modification. !!! info 📎 aquilia/controller/base.py:639-652 **Signature:** The hook receives the response object and must return a (potentially modified) response. DI Constructor Injection Controllers support dependency injection through constructor parameters: !!! info 📎 aquilia/controller/base.py:497-662 Constructor parameters are automatically resolved from the dependency injection container. The controller factory analyzes the constructor signature and resolves dependencies at runtime. !!! warning ⚠️ Constructor analysis implemented in factory.py (not inspected in current session). Template Rendering Controllers provide a built-in `render` method for template rendering: !!! info 📎 aquilia/controller/base.py:566-611 **Signature:** The render method: - Accepts template name and context dictionary - Automatically injects request context if available - Supports custom template engine via parameter or `_template_engine` attribute - Returns a Response object with rendered HTML !!! info 📎 aquilia/controller/base.py:566-611 If `request_ctx` is not provided, the method attempts to retrieve it from the current context automatically. !!! 

### Code Examples
```python
from aquilia import Controller, GET

class UsersController(Controller):
    prefix = "/users"
    
    @GET("/")
    async def list(self, ctx):
        return {"users": []}

```

```python
class UsersController(Controller):
    prefix = "/api/users"

```

```python
class UsersController(Controller):
    prefix = "/users"
    pipeline = [Auth.guard()]

```



---

## Framework Docs: docs/docs/controller/renderers.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-renderers`

--- title: "Content Negotiation & Renderers" description: "Multi-format response rendering" icon: lucide/file-code ---Overview Aquilia provides automatic content negotiation through a pluggable renderer system that transforms your Python data structures into multiple response formats. The framework selects the appropriate renderer based on client preferences expressed via the `Accept` header or explicit `?format=` query parameters (lines 1-32). The renderer system enables your API to serve the same data in JSON, XML, YAML, HTML, plain text, or binary MessagePack format without duplicating controller logic. **Key Features:** - Quality-weighted Accept header parsing - Format override via query parameters - Extensible renderer architecture - Built-in renderers for common formats - Automatic charset handling Built-in Renderers Table | Renderer | Media Type | Format Suffix | Charset | Dependencies | |----------|------------|---------------|---------|--------------| | **JSONRenderer** | `application/json` | `json` | `utf-8` | None (stdlib) | | **XMLRenderer** | `application/xml` | `xml` | `utf-8` | None (stdlib) | | **YAMLRenderer** | `application/x-yaml` | `yaml` | `utf-8` | Optional: `pyyaml` | | **PlainTextRenderer** | `text/plain` | `text` | `utf-8` | None (stdlib) | | **HTMLRenderer** | `text/html` | `html` | `utf-8` | None (stdlib) | | **MessagePackRenderer** | `application/msgpack` | `msgpack` | None (binary) | Required: `msgpack` | All renderers are defined in lines 43-294, with JSONRenderer serving as the default (lines 141-163). Negotiation Priority The content negotiation engine resolves the output format in this order (lines 314-363): 1. **Explicit `?format=` query parameter** — Matches against renderer `format_suffix` 2. **Accept header negotiation** — Uses quality factors and wildcard matching 3. **First renderer in the list** — Falls back to the default renderer This three-tier priority ensures clients can explicitly request formats while still respecting standard HTTP content negotiation (lines 307-313). BaseRenderer API All renderers inherit from `BaseRenderer` (lines 118-138), which defines the contract: **Required Attributes:** - `media_type` — MIME type for Content-Type header - `format_suffix` — Short identifier for `?format=` parameter - `charset` — Character encoding (or `None` for binary) **Required Method:** - `render()` — Converts Python data to string or bytes Accept Header Parsing The `_parse_accept()` function (lines 51-83) implements RFC-compliant Accept header parsing with quality factor support: **Features:** - Extracts quality factors from `q=` parameters (lines 69-74) - Defaults to `q=1.0` when unspecified (line 67) - Sorts entries by quality descending (line 77) - Returns `[("*/*", 1.0)]` for empty/missing headers (line 54) The `_media_matches()` helper (lines 86-96) supports wildcard matching: - `*/*` matches any renderer - `application/*` matches any `application/` media type - Exact match for specific types Controller-level renderer_classes Set `renderer_classes` on your controller to define available renderers (lines 18-27 in docstring): When you return data directly, Aquilia's response pipeline uses the `ContentNegotiator` (lines 299-363) to select and invoke the appropriate renderer. Route-level Override Override renderers for specific routes by configuring the route decorator or manually invoking the negotiation: Route-level control is achieved by calling `negotiate()` directly (lines 374-394). negotiate() Function The `negotiate()` convenience function provides one-shot content negotiation (lines 374-394): **Parameters:** - `data` — Python object to render - `request` — Request object with Accept header and query params - `renderers` — Optional list of renderers (defaults to `[JSONRenderer()]`) - `status` — HTTP status code (default: 200) - `headers` — Additional response headers **Returns:** - Tuple of `(body, content_type, status_code)` **Implementation Details:** - Creates a `ContentNegotiator` instance (line 385) - Selects renderer via `select_renderer()` (line 386) - Invokes `render()` with context (lines 388-393) - Appends charset to Content-Type if applicable (lines 395-397) MessagePackRenderer The `MessagePackRenderer` (lines 277-294) provides binary serialization for high-performance APIs: **Installation:** **Usage:** **Behavior:** - Returns raw `bytes` instead of string (line 284) - Uses `msgpack.packb()` with `use_bin_type=True` (line 284) - Falls back to `str()` serialization for non-packable types (line 284) - Raises `ConfigMissingFault` if `msgpack` is not installed (lines 286-290) The renderer sets `charset = None` (line 281) to indicate binary content. Custom Renderer Create custom renderers by subclassing `BaseRenderer` and implementing the contract: **Register your custom renderer:** **Client requests:** Code Examples Multi-format API Endpoint **Client requests:** Manual Negotiation with Custom Headers Quality Factor Negotiation Conditional Renderer Sel

### Code Examples
```python
GET /api/products?format=xml
   
```

```python
Accept: application/json;q=0.9, text/html;q=0.8
   
```

```python
class BaseRenderer:
    """Abstract renderer."""
    
    media_type: str = "application/octet-stream"
    format_suffix: str = ""  # e.g., "json", "xml"
    charset: str | None = "utf-8"
    
    def render(
        self,
        data: Any,
        *,
        request: Any = None,
        response_status: int = 200,
        response_headers: dict[str, str] | None = None,
    ) -> str | bytes:
        """Render data to the target format."""
        raise NotImplementedError

```



---

## Framework Docs: docs/docs/controller/request-context.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-request-context`

--- title: "Request Context" description: "Understanding the RequestCtx object" icon: lucide/arrow-left-right --- What is RequestCtx? `RequestCtx` is the request context object provided to all controller methods in Aquilia. It encapsulates the HTTP request along with authentication, session, dependency injection container, and other request-scoped data. !!! info "Implementation" Lines 60-68 in `base.py`: RequestCtx uses `__slots__` for compact memory layout and faster attribute access. It's pooled via `_RequestCtxPool` to eliminate per-request heap allocation while still allowing middleware/plugins to attach data via the `state` dict or `_extra` dict. The RequestCtx provides a clean, unified interface for accessing request data, authentication state, and framework services without coupling your handlers to low-level ASGI interfaces. --- Slots RequestCtx uses `__slots__` to define a fixed set of attributes, providing significant performance benefits: !!! info "Performance Rationale" Lines 4-7 in `base.py`: Using `__slots__` provides ~40% faster attribute access compared to regular `__dict__`-based instances. The object pool (`_RequestCtxPool`) eliminates per-request allocation by recycling RequestCtx objects using a pre-allocated ring buffer where `acquire()` resets fields in-place. Benefits of Slots - **Memory efficiency**: Each instance saves ~200+ bytes by not having a `__dict__` - **Faster attribute access**: Direct memory offsets instead of dictionary lookups - **Better cache locality**: Compact memory layout improves CPU cache utilization - **Pool-friendly**: Fixed size enables efficient object pooling --- Constructor Parameters The RequestCtx constructor accepts the following parameters: !!! info "Source Reference" Lines 79-90 in `base.py`: Constructor signature with all parameters, types, and defaults. Parameter Details | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `request` | `Request` | *required* | The underlying HTTP request object | | `identity` | `Optional[Identity]` | `None` | Authenticated user identity (set by auth middleware) | | `session` | `Optional[Session]` | `None` | Session object for stateful interactions | | `auth` | `Any \| None` | `None` | Additional authentication data | | `container` | `Any \| None` | `None` | Dependency injection container | | `state` | `dict[str, Any] \| None` | `None` | Request-scoped state dictionary (shared across middleware) | | `request_id` | `str \| None` | `None` | Unique request identifier for tracing | --- Properties RequestCtx provides convenient read-only properties that delegate to the underlying request object: path Returns the request path (e.g., `/users/123`). !!! info "Source Reference" Line 135-137 in `base.py`: Path property delegates to `self.request.path`. method Returns the HTTP method (e.g., `GET`, `POST`, `PUT`, `DELETE`). !!! info "Source Reference" Line 139-141 in `base.py`: Method property delegates to `self.request.method`. headers Returns the request headers as a `Headers` object (case-insensitive multi-value mapping). !!! info "Source Reference" Line 143-145 in `base.py`: Headers property delegates to `self.request.headers`. query_params Returns parsed query string parameters as a `MultiDict` (supports multiple values per key). !!! info "Source Reference" Line 147-149 in `base.py`: Query params property delegates to `self.request.query_params`. query_param Helper Convenience method to get a single query parameter value. !!! info "Source Reference" Line 151-153 in `base.py`: Delegates to `self.request.query_param()`. --- Async Methods RequestCtx provides async methods for reading and parsing the request body: json Parse the request body as JSON and return the deserialized Python object. !!! info "Source Reference" Line 155-157 in `base.py`: Delegates to `await self.request.json()`. **Example:** body Read the raw request body as bytes. !!! info "Source Reference" Line 159-161 in `base.py`: Delegates to `await self.request.body()`. **Example:** form Parse the request body as `application/x-www-form-urlencoded` or `multipart/form-data` and return a `FormData` object. !!! info "Source Reference" Line 163-165 in `base.py`: Delegates to `await self.request.form()`. **Example:** multipart Parse `multipart/form-data` for file uploads. Returns the parsed multipart data. !!! info "Source Reference" Line 167-169 in `base.py`: Delegates to `await self.request.multipart()`. **Example:** --- Effect Methods Effects are managed resources (database connections, file handles, etc.) that are acquired and released automatically per request. get_effect Get an acquired effect resource by name. Raises `KeyError` if the effect is not found. !!! info "Source Reference" Line 92-96 in `base.py`: Delegates to `self.request.get_effect(name)`. **Example:** has_effect Check if an effect resource is currently acquired. Returns `True` if the effect exists, `False` otherwise. !!! info "Source Reference" Line 98-102 in `b

### Code Examples
```python
__slots__ = (
    "request",
    "identity",
    "session",
    "auth",
    "container",
    "state",
    "request_id",
    "_extra",
)

```

```python
def __init__(
    self,
    request: Request,
    identity: Optional[Identity] = None,
    session: Optional[Session] = None,
    auth: Any | None = None,
    container: Any | None = None,
    state: dict[str, Any] | None = None,
    request_id: str | None = None,
)

```

```python
@property
def path(self) -> str

```



---

## Framework Docs: docs/docs/controller/interceptors.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-interceptors`

--- title: "Interceptors" description: "Request/response interceptors" icon: lucide/waypoints ---Purpose Interceptors wrap handler execution with before/after logic, enabling cross-cutting concerns like logging, caching, timing, authentication checks, and response transformation. They provide a clean separation between business logic and infrastructure concerns. Common use cases: - **Logging and monitoring**: Record request/response timing and metadata - **Caching**: Check cache before handler execution, store results after - **Response transformation**: Add computed fields, format data, inject headers - **Request validation**: Perform additional validation before handler runs - **Audit trails**: Track who accessed what and when Interceptor API The `Interceptor` base class defines before/after hooks (lines 333-370): `before` Method Signature - **`ctx`**: The current request context - **Returns**: - `None` to continue to the handler - A `Response` object to short-circuit execution (see Short-circuiting section) The `before` method is invoked before the controller handler executes. Use it to: - Set up request-scoped state in `ctx.state` - Perform validation or authorization checks - Check caches or early-exit conditions `after` Method Signature - **`ctx`**: The current request context - **`result`**: The return value from the controller handler - **Returns**: The transformed result (or the original result if no transformation) The `after` method is invoked after the handler completes successfully. Use it to: - Transform handler results (add fields, format data) - Add computed metadata - Log results or send metrics Registration Interceptors are registered at the controller class level using the `interceptors` attribute (line 436): The `interceptors` list is automatically copied for each controller class by the `_ControllerMeta` metaclass (lines 427-440), ensuring each controller has its own list. Short-circuiting If the `before()` method returns a `Response` object instead of `None`, the handler execution is **short-circuited**—the handler never runs, and the response is returned immediately. This is useful for: - Returning cached responses without hitting the handler - Rejecting requests early (custom authorization, rate limiting) - Implementing fast-path optimizations **Example:** When `before()` returns a `Response`: - The controller handler is **not executed** - The `after()` method **is still called** with the short-circuit response as `result` - Exception filters do not apply (no exception was raised) Result Transformation The `after()` method receives the handler's return value and can transform it before it's converted into an HTTP response. **Common transformations:** - Add computed fields (timestamps, pagination metadata) - Inject context-specific data (user preferences, feature flags) - Format or normalize data structures - Add response headers via `ctx.state` **Example:** Working Example Here's a complete timing interceptor that measures handler execution time: **Output example:** Interceptor vs Pipeline Both interceptors and pipelines provide request/response processing, but they serve different purposes: | Feature | Interceptor | Pipeline | |---------|-------------|----------| | **Scope** | Controller-level | Route-level or controller-level | | **Use case** | Cross-cutting concerns (timing, logging, caching) | Request validation, auth, dependency injection | | **API** | `before()` / `after()` methods | `run()` method returning `Request` or `Response` | | **Short-circuit** | Return `Response` from `before()` | Return `Response` from `run()` | | **Result transformation** | Yes, via `after()` | No (works with request/response only) | | **Execution order** | After pipeline, wraps handler | Before handler, before interceptors | | **Registration** | `interceptors = [...]` | `pipeline = [...]` | **Execution flow:** **When to use what:** - **Use pipelines** for: Authentication, authorization, input validation, dependency injection - **Use interceptors** for: Logging, timing, caching, response transformation, audit trails Both can be used together—pipelines handle request processing and access control, while interceptors handle cross-cutting concerns and response enhancement.

### Code Examples
```python
class Interceptor:
    async def before(self, ctx: "RequestCtx") -> Optional["Response"]:
        """
        Called before the handler executes.
        
        Return a ``Response`` to short-circuit the handler.
        Return ``None`` to continue.
        """
        return None

    async def after(
        self,
        ctx: "RequestCtx",
        result: Any,
    ) -> Any:
        """
        Called after the handler executes.
        
        Receives the handler result and can transform it.
        """
        return result

```

```python
async def before(self, ctx: RequestCtx) -> Optional[Response]

```

```python
async def after(self, ctx: RequestCtx, result: Any) -> Any

```



---

## Framework Docs: docs/docs/controller/filtering.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-filtering`

--- title: "Filtering, Search & Ordering" description: "Filter, search, and order querysets" icon: lucide/filter ---Overview Aquilia's filter system provides declarative filtering, searching, and ordering for your API endpoints. The system automatically parses query parameters and applies them to both ORM querysets and in-memory lists (lines 1-30). Key features: - **FilterSet**: Declarative field-based filtering with 20+ lookup types - **SearchFilter**: Multi-field text search via `?search=<term>` - **OrderingFilter**: Dynamic ordering via `?ordering=<field>` - **Custom backends**: Implement `BaseFilterBackend` for full control - **ReDoS prevention**: Built-in regex safety guards - **Auto-application**: Filters apply automatically when configured on routes FilterSet (declarative field filtering, lookup types) `FilterSet` provides declarative field-based filtering with support for 20+ lookup operators (lines 289-369). Define a class with a `Meta` inner class specifying which fields and lookups to enable. Supported Lookup Types The system supports extensive lookup operators (lines 98-122): | Lookup | Description | Example Query | |--------|-------------|---------------| | `exact` | Exact match (default) | `?status=active` | | `iexact` | Case-insensitive exact match | `?name__iexact=john` | | `contains` | Substring match (case-sensitive) | `?title__contains=Python` | | `icontains` | Substring match (case-insensitive) | `?title__icontains=python` | | `startswith` | Starts with | `?code__startswith=PRD` | | `istartswith` | Starts with (case-insensitive) | `?code__istartswith=prd` | | `endswith` | Ends with | `?email__endswith=@example.com` | | `iendswith` | Ends with (case-insensitive) | `?email__iendswith=@EXAMPLE.COM` | | `gt` | Greater than | `?price__gt=100` | | `gte` | Greater than or equal | `?price__gte=100` | | `lt` | Less than | `?price__lt=500` | | `lte` | Less than or equal | `?price__lte=500` | | `in` | In list (comma-separated) | `?status__in=active,pending` | | `range` | Between two values | `?price__range=100,500` | | `isnull` | Is null (true/false) | `?deleted_at__isnull=false` | | `regex` | Regex match | `?sku__regex=^[A-Z]{3}` | | `iregex` | Regex match (case-insensitive) | `?sku__iregex=^[a-z]{3}` | | `ne` | Not equal | `?status__ne=deleted` | | `date` | Date portion of datetime | `?created_at__date=2024-01-15` | | `year` | Year of date/datetime | `?created_at__year=2024` | | `month` | Month of date/datetime | `?created_at__month=12` | | `day` | Day of date/datetime | `?created_at__day=25` | Basic Usage Query examples: Custom Filter Methods Define `filter_<field>` methods to override default behavior (lines 340-352): Value Coercion Query string values are automatically coerced to appropriate Python types (lines 127-159): - **Numeric**: `"123"` → `123`, `"12.5"` → `12.5` - **Boolean**: `"true"`, `"false"`, `"1"`, `"0"`, `"yes"`, `"no"`, `"on"` - **Dates**: ISO 8601 formats (`YYYY-MM-DD`, `YYYY-MM-DDTHH:MM:SS`) - **Lists**: Comma-separated for `in` and `range` lookups Manual Usage Use FilterSet outside the auto-application system (lines 370-387): filterset_fields Shorthand For simple exact-match filtering, use `filterset_fields` instead of creating a FilterSet class (lines 490-510): Query: `GET /products?status=active&category=electronics` For multiple lookups per field, use dict form: Query: `GET /products?price__gte=100&name__icontains=laptop` The engine creates an ad-hoc FilterSet class internally (lines 497-503). SearchFilter (search param, search_fields) `SearchFilter` enables multi-field text search via a single `?search=` query parameter (lines 431-467). Configuration Query: `GET /products?search=laptop` Behavior - **ORM mode**: Builds an OR chain with `icontains` lookups (lines 452-461) - **List mode**: Case-insensitive substring match across all search fields (lines 443-449) - An item matches if **any** search field contains the search term Custom Search Parameter Change the query parameter name (line 438): Query: `GET /products?q=laptop` ORM Implementation For ORM querysets, SearchFilter builds a Q-node OR chain (lines 452-461): In-Memory Implementation For lists, uses case-insensitive substring matching (lines 271-283): OrderingFilter (ordering param, minus-prefix) `OrderingFilter` enables dynamic field ordering via `?ordering=` query parameter (lines 470-515). Configuration Query Syntax Security: Field Whitelisting Only fields in `ordering_fields` are allowed (lines 491-497). This prevents arbitrary field access: Custom Ordering Parameter Query: `GET /products?sort=-price,name` In-Memory Implementation For lists, uses a custom comparator (lines 286-315): BaseFilterBackend (custom backends) Create custom filter backends by subclassing `BaseFilterBackend` (lines 403-428): Custom Backend Example Combining Multiple Backends Backends are applied in sequence: ReDoS Prevention The filter system includes built-in protection against Regular Expression Denial of Service (ReDoS) attacks (lines 

### Code Examples
```python
from aquilia import Controller, GET, FilterSet, SearchFilter, OrderingFilter

class ProductFilter(FilterSet):
    class Meta:
        fields = {
            "category": ["exact"],
            "price": ["gte", "lte", "range"],
            "is_active": ["exact"],
            "name": ["icontains"],
        }

class ProductsController(Controller):
    prefix = "/products"
    
    @GET("/", filterset_class=ProductFilter,
         search_fields=["name", "description"],
         ordering_fields=["price", "created_at", "name"])
    async def list_products(self, ctx):
        products = await Product.objects.all()
        return products  # engine auto-applies filter → search → order

```

```python
class ProductFilter(FilterSet):
    class Meta:
        fields = {
            "category": ["exact", "in"],
            "price": ["gte", "lte", "range"],
            "is_active": ["exact"],
            "name": ["icontains"],
            "created_at": ["date", "year", "month"],
        }

# In your controller
@GET("/products", filterset_class=ProductFilter)
async def list_products(self, ctx):
    products = await Product.objects.all()
    return products

```

```python
GET /products?category=electronics
GET /products?price__gte=100&price__lte=500
GET /products?name__icontains=laptop
GET /products?category__in=electronics,books
GET /products?created_at__year=2024

```



---

## Framework Docs: docs/docs/controller/openapi.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-openapi`

--- title: "OpenAPI Generation" description: "How to generate and serve OpenAPI documentation for Aquilia applications" icon: lucide/file-text ---Aquilia features built-in support for generating OpenAPI 3.1.0 specifications directly from controllers. By introspecting controller class metadata, handler signatures, type hints, docstrings, and pipeline guards, Aquilia can compile a complete API schema and serve interactive documentation using Swagger UI or ReDoc. The core OpenAPI generation capabilities are implemented in [aquilia/controller/openapi.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py). --- Configuration with OpenAPIConfig The [OpenAPIConfig](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578) dataclass (defined in [openapi.py:L578-L633](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578-L633)) defines parameters for configuring OpenAPI generation, paths, external docs, and UI themes. Parameters Reference | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `title` | `str` | `"Aquilia API"` | The title of the API. | | `version` | `str` | `"1.0.0"` | The version of the API. | | `description` | `str` | `""` | A comprehensive description of the API. | | `terms_of_service` | `str` | `""` | URL to the terms of service. | | `contact_name` | `str` | `""` | Contact name for the API. | | `contact_email` | `str` | `""` | Contact email address. | | `contact_url` | `str` | `""` | Contact URL. | | `license_name` | `str` | `""` | Name of the license. | | `license_url` | `str` | `""` | URL to the license terms. | | `servers` | `list[dict[str, str]]` | `[]` | List of server URL and description dictionaries representing deployment targets. | | `docs_path` | `str` | `"/docs"` | Path where the Swagger UI documentation is served. | | `openapi_json_path` | `str` | `"/openapi.json"` | Path where the raw OpenAPI JSON specification is served. | | `redoc_path` | `str` | `"/redoc"` | Path where the ReDoc documentation is served. | | `include_internal` | `bool` | `False` | Whether to include internal routes starting with `/_`. | | `group_by_module` | `bool` | `True` | Whether to group tags by module. | | `infer_request_body` | `bool` | `True` | Whether to automatically infer request body schemas from handler signatures, type hints, and source code. | | `infer_responses` | `bool` | `True` | Whether to automatically infer response schemas from handler source code and route metadata. | | `detect_security` | `bool` | `True` | Whether to detect security schemes and requirements from controller and route pipeline guards. | | `external_docs_url` | `str` | `""` | URL for external documentation. | | `external_docs_description` | `str` | `""` | Description for the external documentation. | | `swagger_ui_theme` | `str` | `""` | Theme for Swagger UI. Supports `"dark"` or custom themes. | | `swagger_ui_config` | `dict[str, Any]` | | Additional configuration options passed directly to the SwaggerUIBundle constructor. | | `enabled` | `bool` | `True` | Global flag to enable or disable OpenAPI generation features. | Configuration Helper Method - **`from_dict(data)`** ([openapi.py:L624-L632](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L624-L632)): A class method that constructs an [OpenAPIConfig](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578) object from a dictionary (e.g. workspace configuration), ignoring keys starting with `_` and verifying parameter existence on the configuration object. --- Specification Generation with OpenAPIGenerator The [OpenAPIGenerator](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L638) class (defined in [openapi.py:L638-L961](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L638-L961)) is the primary engine responsible for compiling routing structures into a fully compliant OpenAPI 3.1.0 specification. Constructor and Initialization The constructor ([openapi.py:L666-L681](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L666-L681)) accepts an optional [OpenAPIConfig](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578) object. If omitted, it initializes a default configuration using the provided `title` and `version` parameters. The generate() Method The [generate()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L683-L757) method takes a [ControllerRouter](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/router.py) instance and generates a complete OpenAPI 3.1.0 specification dictionary containing: - **`openapi`**: The specification version, pinned to `"3.1.0"` ([openapi.py:L711](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L711)). - **`info`**: An info object built by `_build_inf

### Code Examples
```python
def __init__(
    self,
    title: str = "Aquilia API",
    version: str = "1.0.0",
    config: OpenAPIConfig | None = None,
):

```

```python
def generate(self, router: ControllerRouter) -> dict[str, Any]:

```

```python
from aquilia.controller import Controller, GET, Response
from aquilia.controller.router import ControllerRouter
from aquilia.controller.openapi import (
    OpenAPIConfig,
    OpenAPIGenerator,
    generate_swagger_html,
    generate_redoc_html,
)

class DocsController(Controller):
    tags = ["System"]

    def __init__(self, router: ControllerRouter):
        self.router = router
        self.config = OpenAPIConfig(
            title="Aquilia Application API",
            version="1.4.0",
            description="Documentation for the main application API services.",
            docs_path="/docs",
            openapi_json_path="/docs/openapi.json",
            redoc_path="/docs/redoc"
        )
        self.generator = OpenAPIGenerator(config=self.config)

    @GET("/openapi.json")
    async def get_openapi_json(self):
        """Get raw OpenAPI 3.1.0 specification JSON."""
        spec = self.generator.generate(self.router)
        return Response.json(spec)

    @GET("/")
    async def get_swagger_docs(self):
        """Render the Swagger UI documentation interactive console."""
        html = generate_swagger_html(self.config)
        return Response.html(html)

    @GET("/redoc")
    async def get_redoc_docs(self):
        """Render the ReDoc api reference console."""
        html = generate_redoc_html(self.config)
        return Response.html(html)

```



---

## Framework Docs: docs/docs/controller/exception-filters.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-exception-filters`

--- title: "Exception Filters" description: "Handling exceptions with filters" icon: lucide/shield-alert ---Purpose Exception filters intercept unhandled exceptions from controller handlers and convert them into proper HTTP responses. This provides a centralized, declarative way to handle errors across your controller methods without repetitive try-catch blocks. Exception filters are useful for: - Converting domain exceptions (e.g., `KeyError`, `ValueError`) into appropriate HTTP error responses - Standardizing error response formats across your API - Adding context-aware error handling (logging, monitoring, custom headers) - Separating error handling logic from business logic ExceptionFilter API The `ExceptionFilter` base class defines the contract for exception filters (lines 294-327): `catches` Attribute A class-level list of exception types that this filter will handle. When an exception is raised from a controller handler, Aquilia checks each registered filter's `catches` list to find a matching handler. `catch` Method Signature - **`exception`**: The exception instance that was raised - **`ctx`**: The current request context, providing access to request data, identity, session, etc. - **Returns**: A `Response` object to send to the client, or `None` to let the exception propagate further Registration Exception filters are registered at the controller class level using the `exception_filters` attribute (line 437): The `exception_filters` list is automatically copied for each controller class by the `_ControllerMeta` metaclass (lines 427-440), preventing list mutation from affecting parent classes. Working Example Here's a practical example of a custom 404 filter that catches lookup errors: Execution Order Exception filters are evaluated in the order they appear in the `exception_filters` list. When an exception is raised: 1. Aquilia iterates through the registered filters in order 2. For each filter, it checks if the exception type is in the filter's `catches` list 3. The first matching filter's `catch()` method is invoked 4. If `catch()` returns a `Response`, that response is sent to the client 5. If `catch()` returns `None`, the exception continues to the next filter 6. If no filter handles the exception, it propagates to the framework's default error handler **Example with multiple filters:** Best practices: - Place more specific filters before generic ones - Return `None` from `catch()` if you want to delegate to the next filter - Use separate filters for different error categories (validation, not found, auth, etc.) - Include request context in error responses for debugging (`request_id`, `path`)

### Code Examples
```python
class ExceptionFilter:
    catches: list[type] = []  # Exception types this filter handles

    async def catch(
        self,
        exception: Exception,
        ctx: "RequestCtx",
    ) -> Optional["Response"]:
        """
        Handle the exception and return a Response.
        
        Return ``None`` to let the exception propagate.
        """
        raise NotImplementedError

```

```python
async def catch(self, exception: Exception, ctx: RequestCtx) -> Optional[Response]

```

```python
class UsersController(Controller):
    prefix = "/users"
    exception_filters = [NotFoundFilter(), ValidationFilter()]

```



---

## Framework Docs: docs/docs/controller/http-decorators.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-http-decorators`

--- title: "HTTP Decorators" description: "Route decorators for defining HTTP endpoints" icon: lucide/braces --- Overview !!! info HTTP decorators attach metadata to controller methods for compile-time extraction without import-time side effects (lines 30-177). All HTTP method decorators inherit from the `RouteDecorator` base class, which provides a declarative interface for defining routes. The decorator system uses Python's function metadata (`__route_metadata__`) to store route configuration that is later compiled by the framework. !!! info The base `RouteDecorator.__call__` method attaches metadata to functions and performs deduplication to prevent the same method+path combination from being registered twice (lines 140-145). Key Features - **Metadata-driven**: Decorators attach metadata without executing logic at import time - **Deduplication**: Prevents duplicate route registration for the same method+path pair (lines 140-145) - **Version binding**: Supports route-level API versioning (lines 164-172) - **Pipeline support**: Override controller-level pipelines per route - **OpenAPI integration**: Automatic documentation generation from decorator parameters Decorator Inventory Aquilia provides decorators for all standard HTTP methods plus WebSocket support: | Decorator | HTTP Method | Line Range | Description | |-----------|-------------|------------|-------------| | `@GET` | GET | 180-227 | Retrieve resources | | `@POST` | POST | 230-277 | Create resources | | `@PUT` | PUT | 280-327 | Replace resources | | `@PATCH` | PATCH | 330-377 | Partial updates | | `@DELETE` | DELETE | 380-427 | Remove resources | | `@HEAD` | HEAD | 430-477 | Headers-only GET | | `@OPTIONS` | OPTIONS | 480-527 | Supported methods | | `@TRACE` | TRACE | 530-577 | Diagnostic echo | | `@WS` | WebSocket | 580-627 | WebSocket handler | | `@route()` | Custom/Multiple | 630-739 | Multi-method decorator | !!! info Valid HTTP methods are defined in `VALID_HTTP_METHODS` frozenset (lines 13-23): GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE, and WS. Universal Parameters All `RouteDecorator` subclasses accept the following parameters in their `__init__` method (lines 37-122): Path & Method | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `path` | `str \| None` | `None` | URL path template (e.g., `"/"`, `"/{id:int}"`) - derives from method name if None | | `method` | `str \| None` | Set by subclass | HTTP method (GET, POST, etc.) | OpenAPI Documentation | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `summary` | `str \| None` | `None` | OpenAPI summary | | `description` | `str \| None` | `None` | OpenAPI description | | `tags` | `list[str] \| None` | `None` | OpenAPI tags (extends class-level) | | `deprecated` | `bool` | `False` | Mark as deprecated in OpenAPI | Request/Response Configuration | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `response_model` | `type \| None` | `None` | Response type for OpenAPI | | `status_code` | `int` | `200` | Default HTTP status code | | `request_contract` | `type \| None` | `None` | Aquilia Contract class for request body casting and sealing | | `response_contract` | `type \| None` | `None` | Aquilia Contract class (or ProjectedRef) for response molding | Filtering, Searching, Ordering !!! info Filter parameters (lines 56-59) enable declarative query parameter filtering without manual parsing. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `filterset_class` | `type \| None` | `None` | FilterSet subclass for declarative filtering | | `filterset_fields` | `list[str] \| Any \| None` | `None` | List of field names (exact-match) or dict mapping fields to lookup lists | | `search_fields` | `list[str] \| None` | `None` | Field names for text search (activated via `?search=<term>`) | | `ordering_fields` | `list[str] \| None` | `None` | Fields allowed for dynamic ordering (activated via `?ordering=<field>`) | Pagination | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `pagination_class` | `type \| None` | `None` | Pagination backend (PageNumberPagination, LimitOffsetPagination, CursorPagination) | Content Negotiation | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `renderer_classes` | `list[Any] \| None` | `None` | List of renderer instances/classes for content negotiation | Performance & Security | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `pipeline` | `list[Any] \| None` | `None` | Method-level pipeline nodes (overrides class-level) | | `throttle` | `Any \| None` | `None` | Per-route Throttle override | | `timeout` | `float \| None` | `None` | Per-route handler timeout (seconds) | API Versioning !!! info The `version` parameter (lines 71-74, 164-172) binds routes to specific API versions, overriding con

### Code Examples
```python
@route(method: str | list[str], path: str | None = None, **kwargs)

```

```python
# Single method
@route("GET", "/users")
async def get_users(self, ctx):
    ...

# Multiple methods
@route(["GET", "POST"], "/items")
async def handle_items(self, ctx):
    if ctx.method == "GET":
        # Handle GET
        ...
    else:
        # Handle POST
        ...

```

```python
from aquilia.controller import Controller, WS

class ChatController(Controller):
    prefix = "/chat"
    
    @WS("/ws")
    async def websocket_handler(self, ctx):
        websocket = ctx.request.websocket
        
        await websocket.accept()
        
        try:
            while True:
                message = await websocket.receive_text()
                await websocket.send_text(f"Echo: {message}")
        except Exception:
            await websocket.close()

```



---

## Framework Docs: docs/docs/controller/api-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-controller-api-reference`

--- title: "Controller API Reference" description: "Comprehensive reference of all public symbols exported by the aquilia.controller module." icon: lucide/terminal --- This page documents all public symbols exported by the [aquilia.controller](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py) module. --- Base Architecture [Controller](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L497-L662) Base Controller class. Replaces function-based handlers with class-based routing, lifecycle hooks, and dependency injection. Class Attributes | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `prefix` | `str` | `""` | URL prefix prepended to all routes in this controller. | | `pipeline` | `list[Any]` | `[]` | List of pipeline nodes applied to all handlers in this controller. | | `tags` | `list[str]` | `[]` | OpenAPI tags applied to all handlers for API documentation. | | `instantiation_mode` | `"per_request" \| "singleton"` | `"per_request"` | Governs controller instantiation lifecycle. | | `version` | `str \| None` | `None` | API version string (e.g., "v1", "v2"). | | `throttle` | `Throttle \| None` | `None` | Rate limiting configuration applied to this controller. | | `interceptors` | `list[Any]` | `[]` | List of Interceptor instances to wrap handler execution. | | `exception_filters` | `list[Any]` | `[]` | List of ExceptionFilter instances to catch unhandled errors. | | `timeout` | `float` | `0` | Handler execution timeout in seconds (0 = disabled). | | `max_body_size` | `int` | `0` | Max request body size in bytes (0 = no limit). | Methods - **`render(self, template_name: str, context: dict[str, Any] | None = None, request_ctx: RequestCtx | None = None, *, engine: Any | None = None, status: int = 200, headers: dict[str, str] | None = None) -> Response`** - Renders a template using the template engine and returns a Response. - **`on_startup(self, ctx: RequestCtx) -> None`** - Asynchronous lifecycle hook called when the controller is initialized (singleton mode only). - **`on_shutdown(self, ctx: RequestCtx) -> None`** - Asynchronous lifecycle hook called when the controller is destroyed (singleton mode only). - **`on_request(self, ctx: RequestCtx) -> None`** - Asynchronous lifecycle hook called before each request is processed. - **`on_response(self, ctx: RequestCtx, response: Response) -> Response`** - Asynchronous lifecycle hook called to post-process the response before sending it. * **Evidence**: [aquilia/controller/base.py:L497-L662](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L497-L662) --- [RequestCtx](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L55-L168) Request context provided to controller handlers. Uses `__slots__` and object pooling for maximum performance. Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `request` | `Request` | | The active ASGI request. | | `identity` | `Optional[Identity]` | `None` | Authenticated user identity (if available). | | `session` | `Optional[Session]` | `None` | Active session object. | | `auth` | `Any \| None` | `None` | Parsed auth token or credentials. | | `container` | `Any \| None` | `None` | Request-scoped Dependency Injection container. | | `state` | `dict[str, Any] \| None` | `None` | State dictionary for middleware metadata. | | `request_id` | `str \| None` | `None` | Unique request ID for tracing. | * **Evidence**: [aquilia/controller/base.py:L55-L168](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L55-L168) --- [ExceptionFilter](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L260-L296) Base class for exception filters to convert unhandled exceptions into HTTP responses. Parameters (catch) | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `exception` | `Exception` | | The exception raised during route handling. | | `ctx` | `RequestCtx` | | The active request context. | * **Returns**: `Optional[Response]` - Return `None` to let the exception propagate, or a `Response` to short-circuit. * **Evidence**: [aquilia/controller/base.py:L260-L296](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L260-L296) --- [Interceptor](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L303-L348) Base class for interceptors to wrap handler execution with before/after logic. * **Evidence**: [aquilia/controller/base.py:L303-L348](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L303-L348) --- [Throttle](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L355-L461) Simple in-memory sliding-window rate limiter with LRU eviction and expired entry cleanup to prevent memory growth. Parameters | Field | Type | Default | Description | | :--- | :--- | :--- | :--- | | `limit` | `int` | `100` | Max requests 

### Code Examples
```python
class Controller(metaclass=_ControllerMeta):
    prefix: str = ""
    pipeline: list[Any] = []
    tags: list[str] = []
    instantiation_mode: str = "per_request"
    version: str | None = None
    throttle: Throttle | None = None
    interceptors: list[Any] = []
    exception_filters: list[Any] = []
    timeout: float = 0
    max_body_size: int = 0

```

```python
class RequestCtx:
    def __init__(
        self,
        request: Request,
        identity: Optional[Identity] = None,
        session: Optional[Session] = None,
        auth: Any | None = None,
        container: Any | None = None,
        state: dict[str, Any] | None = None,
        request_id: str | None = None,
    )

```

```python
class ExceptionFilter:
    catches: list[type] = []

    async def catch(
        self,
        exception: Exception,
        ctx: RequestCtx,
    ) -> Optional[Response]

```



---

## Framework Docs: docs/docs/getting-started/concepts.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-getting-started-concepts`

--- title: "Core Concepts" description: "Understanding the architecture and mental models of Controllers and Contracts" icon: lucide/info ---Aquilia relies on two foundational abstractions to structure web applications: **Controllers** and **Contracts**. Together, they form a highly declarative, statically checkable, and performance-oriented boundary between your database models and the HTTP interface. --- 1. Controller Mental Model Aquilia replaces traditional function-based flow handlers with class-based **Controllers**. They are designed under a manifest-first, dependency-injection-first, and pipeline-first philosophy. Class-Based & Manifest-First Instead of dynamically registering routes at import time via side-effecting decorators, Controllers declare route structures statically. * **Manifest-First**: Controllers are explicitly declared in the `module.aq` manifest. * **Zero Side Effects**: Importing a controller module has no runtime registration side effects. Routing layouts are resolved at build/compile time. * **Implementation**: The base [Controller](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L497-L662) class provides standard lifecycle hooks such as `on_startup`, `on_shutdown`, `on_request`, and `on_response` for request-lifecycle middleware. DI-First (Dependency Injection) Controllers do not manually instantiate their repositories, database connections, or downstream clients. Instead, dependencies are declared via constructor parameters and resolved dynamically. * **Dynamic Resolution**: At runtime, [ControllerFactory](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/factory.py#L24-L402) inspects constructor signatures and method parameters, extracting dependencies from the request/app containers. * **Instantiation Modes**: Supports both `singleton` and `per-request` instantiation. An example of class-based DI and routing is shown in [aquilia/controller/\_\_init\_\_.py:L18-32](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L18-L32): Pipeline-First Controllers support hierarchical, multi-stage request processing pipelines. You can define middleware (such as authentication, logging, and rate-limiting) at both the controller class level and individual route method levels. * **Orchestration**: The pipeline is handled by `_execute_flow_pipeline` in [aquilia/controller/engine.py:L572-665](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/engine.py#L572-L665). * **Guards & Interceptors**: Exception filters and interceptors run sequentially before executing the endpoint, handling errors and cross-cutting concerns declaratively. Static-First (Metadata Extraction) Routing structures, parameter annotations, and OpenAPI schemas are extracted statically before runtime. * **Compiler**: [ControllerCompiler](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/compiler.py#L72-L611) parses route definitions and validates the route tree. * **Metadata**: Parameter and route schemas are gathered via `extract_controller_metadata` in [aquilia/controller/metadata.py:L74](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L74) to generate OpenAPI specifications without executing code. --- 2. Contract Mental Model A **Contract** is not a simple JSON serializer or parser. Instead, it is a **model-to-world contract**. It specifies exactly what database fields are visible, how data enters the application, how constraints are enforced, and how changes are persisted back to the database. The core responsibilities of a Contract cover the following pipeline phases (see [aquilia/contracts/\_\_init\_\_.py:L4-7](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L4-L7)): Facets (Attributes & Visibility) Facets represent individual fields mapped from database columns to external endpoints. They declare type constraints, default values, write-only/read-only rules, and computed properties. * **Base Class**: All fields inherit from `Facet` ([aquilia/contracts/facets.py:L70](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L70)). * **Special Facets**: Includes `Computed` (outbound values resolved via functions), `Constant`, `Hidden`, `ReadOnly`, and `WriteOnly`. Projections (Slices of Visibility) Rather than writing multiple serializers for different endpoints, a single Contract defines multiple named **Projections** (subsets of fields) to reuse models across different views (e.g. `summary` vs `detail`). * **Slicing**: Resolved via subscript notation on the Contract metaclass: `ProductContract["summary"]` ([aquilia/contracts/core.py:L609-624](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L609-L624)). Casts (Type Coercion) Incoming request data is automatically coerced into appropriate Python types (e.g., parsing a string timestamp into a `datetime` object or verifying integers). 

### Code Examples
```python
mermaid
graph TD
    Compile[Compile Time: ControllerCompiler] -->|Extract Metadata| StaticMeta[Controller & Route Metadata]
    StaticMeta -->|Zero Import-Time Side Effects| Startup[Runtime Startup]
    Startup -->|Instantiate per-request/singleton| DI[ControllerFactory DI Injection]
    DI -->|Execute guards/interceptors| Pipeline[Pipeline Execution]
    Pipeline -->|Route Handler| Action[Handler Invocation]

```

```python
class UsersController(Controller):
    prefix = "/users"
    pipeline = [Auth.guard()]

    def __init__(self, repo: Annotated[UserRepo, Inject(tag="repo")]):
        self.repo = repo

    @GET("/")
    async def list(self, ctx):
        return self.repo.list_all()

```

```python
INBOUND FLOW (Write)                   OUTBOUND FLOW (Read)
 ┌──────────────────────────────┐       ┌──────────────────────────────┐
 │     Raw Input Dictionary     │       │     Database Model Class     │
 └──────────────┬───────────────┘       └──────────────┬───────────────┘
                │ (Cast/Coerce)                        │ (Extract Facets)
                ▼                                      ▼
 ┌──────────────────────────────┐       ┌──────────────────────────────┐
 │      Cast Data & Types       │       │    Apply Named Projection    │
 └──────────────┬───────────────┘       └──────────────┬───────────────┘
                │ (Seal/Validate)                      │ (Format Output)
                ▼                                      ▼
 ┌──────────────────────────────┐       ┌──────────────────────────────┐
 │    Sealed Integrity Check    │       │     Serialized JSON Dict     │
 └──────────────┬───────────────┘       └──────────────────────────────┘
                │ (Imprint)
                ▼
 ┌──────────────────────────────┐
 │  Updated Model (DB Persist)  │
 └──────────────────────────────┘

```



---

## Framework Docs: docs/docs/getting-started/quick-start.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-getting-started-quick-start`

--- title: "Quick Start" description: "5-minute hello world CRUD/GET setup in Aquilia" icon: lucide/rocket ---This guide will walk you through a **5-minute end-to-end setup** to define an Aquilia controller, register a contract on the response, and build a full "Hello World" level CRUD API. Aquilia replaces traditional function-based flow handlers with a robust, class-based, metadata-first controller system paired with model-world serialization contracts called Contracts. --- 5-Minute End-to-End GET Setup Here is how you can set up a controller with a single GET route that returns JSON and applies a response serialization Contract. !!! info "How Response Contracts Work" When you register `response_contract=GreetingContract` on a route decorator, the Aquilia engine intercepts the return dict and automatically filters, validates, and serializes it based on the fields defined in the Contract. The `ignored_field` is omitted from the JSON output. --- Hello World CRUD/GET Controller Below is a complete, runnable CRUD controller utilizing an in-memory dictionary to manage resources. This example showcases request payload ingestion, validation, and database updates. --- API Verification & Source Citations All components used in this guide are built on top of Aquilia's verified, first-class APIs: | Component / API | Verified Source & Module | Description / Reference | | :--- | :--- | :--- | | **`Controller`** | [aquilia/controller/\_\_init\_\_.py:L34](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L34) | Class-based handler base class (exported in [L105](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L105)). | | **`GET` / `POST` / `PUT` / `DELETE`** | [aquilia/controller/\_\_init\_\_.py:L41-47](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L41-L47) | Route decorator classes for handling HTTP verbs (exported in [L111-115](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L111-L115)). | | **`RequestCtx`** | [aquilia/controller/\_\_init\_\_.py:L34](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L34) | The request context object passed into every handler (exported in [L106](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L106)). | | **`ctx.json()`** | `.cache/index_controller.json:L83-87` | Asynchronous method on `RequestCtx` to extract the parsed JSON body of a request. | | **`Contract`** | [aquilia/contracts/\_\_init\_\_.py:L41](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L41) | Declares the serialization & validation contracts (exported in [L112](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L112)). | | **`bp.is_sealed()`** | `.cache/index_contracts.json:L95-100` | Checks if inbound data conforms to the Contract constraint seals. | | **`bp.validated_data`** | `.cache/index_contracts.json:L130-135` | Property that yields fully validated and parsed inbound data. | | **`bp.errors`** | `.cache/index_contracts.json:L137-141` | Property yielding a dictionary of validation faults keyed by field name. | | **`response_contract`** | [aquilia/contracts/\_\_init\_\_.py:L35](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L35) | Route-level integration parameter that binds a serializer contract directly to the endpoint response. |

### Code Examples
```python
# hello_controller.py
from aquilia.controller import Controller, GET, RequestCtx
from aquilia.contracts import Contract

# 1. Define a response Contract contract
class GreetingContract(Contract):
    message: str
    status: str

# 2. Define the Controller and route handler
class HelloController(Controller):
    prefix = "/api"

    @GET("/hello", response_contract=GreetingContract)
    async def say_hello(self, ctx: RequestCtx):
        return {
            "message": "Hello, World!",
            "status": "success",
            "ignored_field": "This will be filtered out by the contract"
        }

```

```python
# items_controller.py
from aquilia.controller import Controller, GET, POST, PUT, DELETE, RequestCtx
from aquilia.contracts import Contract

# Simulated database store
ITEMS_DB = {
    1: {"id": 1, "name": "Item A", "price": 10.99},
    2: {"id": 2, "name": "Item B", "price": 20.99},
}

# 1. Define the serialization and validation contract
class ItemContract(Contract):
    id: int
    name: str
    price: float

# 2. Create the Controller to handle CRUD operations
class ItemsController(Controller):
    prefix = "/items"

    @GET("/")
    async def list_items(self, ctx: RequestCtx):
        """Retrieve all items."""
        return list(ITEMS_DB.values())

    @GET("/{id:int}")
    async def get_item(self, ctx: RequestCtx, id: int):
        """Retrieve a specific item by ID."""
        item = ITEMS_DB.get(id)
        if not item:
            return {"error": "Item not found"}, 404
        return item

    @POST("/", response_contract=ItemContract)
    async def create_item(self, ctx: RequestCtx):
        """Create a new item with request validation."""
        # 1. Read request JSON body
        payload = await ctx.json()
        
        # 2. Bind payload to the Contract for validation
        bp = ItemContract(data=payload)
        
        # 3. Check constraints (Seals)
        if not bp.is_sealed():
            return {"errors": bp.errors}, 400
            
        # 4. Save validated data to database
        validated = bp.validated_data
        new_id = max(ITEMS_DB.keys(), default=0) + 1
        new_item = {
            "id": new_id,
            "name": validated["name"],
            "price": validated["price"],
        }
        ITEMS_DB[new_id] = new_item
        return new_item

    @PUT("/{id:int}", response_contract=ItemContract)
    async def update_item(self, ctx: RequestCtx, id: int):
        """Update an existing item."""
        if id not in ITEMS_DB:
            return {"error": "Item not found"}, 404
            
        payload = await ctx.json()
        bp = ItemContract(data=payload)
        
        if not bp.is_sealed():
            return {"errors": bp.errors}, 400
            
        validated = bp.validated_data
        ITEMS_DB[id]["name"] = validated["name"]
        ITEMS_DB[id]["price"] = validated["price"]
        return ITEMS_DB[id]

    @DELETE("/{id:int}")
    async def delete_item(self, ctx: RequestCtx, id: int):
        """Delete an item by ID."""
        if id not in ITEMS_DB:
            return {"error": "Item not found"}, 404
        del ITEMS_DB[id]
        return {"success": True}

```



---

## Framework Docs: docs/docs/getting-started/index.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-getting-started-index`

--- title: "Introduction" description: "Getting started with Aquilia Controller and Contracts modules" icon: lucide/book-marked ---What is Aquilia? Aquilia is a **production-ready async Python web framework** designed for seamless developer experience. It provides deep, complete integration of several advanced components to build robust applications. As defined in the framework initialization ([aquilia/__init__.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/__init__.py#L2-L15)), Aquilia integrates the following modules: * **Aquilary**: Manifest-driven app registry with dependency resolution. * **Flow**: Typed flow-first routing with composable pipelines. * **DI**: Scoped dependency injection with lifecycle management. * **Sessions**: Cryptographic session management with policies. * **Auth**: OAuth2/OIDC, MFA, RBAC/ABAC authorization. * **Faults**: Structured error handling with fault domains. * **Middleware**: Composable middleware with effect awareness. * **Patterns**: Auto-fix, retry, and circuit breaker patterns. --- What These Docs Cover These documentation sections focus specifically on two core modules of the Aquilia ecosystem: 1. Controllers (First-Class Class-Based Routing) The **Controller System** introduces a class-based architecture that replaces function-based `@flow` handlers ([aquilia/controller/__init__.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L2-L6)). Key features of Aquilia Controllers include: * **Manifest-first**: Declared in `module.aq` ([aquilia/controller/__init__.py:8](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L8)). * **DI-first**: Class constructor and method parameter dependency injection ([aquilia/controller/__init__.py:9](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L9)). * **Pipeline-first**: Class-level and method-level pipelines ([aquilia/controller/__init__.py:10](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L10)). * **Static-first**: Metadata extraction at compile time with zero import-time side effects ([aquilia/controller/__init__.py:11-12](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L11-L12)). !!! info Class-based Controllers leverage HTTP verb decorators like `@GET`, `@POST`, and `@PUT` for explicit endpoint definitions ([aquilia/controller/__init__.py:40-52](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/__init__.py#L40-L52)). 2. Contracts (Model ↔ World Contracts) The **Contracts System** provides first-class contracts between internal models and the outside world ([aquilia/contracts/__init__.py](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/__init__.py#L2-L8)). A Contract specifies: * **Facets**: What the world sees (e.g. `TextFacet`, `IntFacet`, `BoolFacet`). * **Projections**: Named subsets of data (e.g. `summary` or `detail` views). * **Casts**: How inbound data enters. * **Seals**: How integrity and validation are enforced. * **Imprints**: How validated data is written back to the model. --- Navigation Guide To help you get started quickly, we recommend navigating the documentation in the following order: 1. **Getting Started** (This Section) * [Introduction](index.md): Overview of the framework. * [Core Concepts](concepts.md): Understanding the fundamental architectural blocks. * [Quick Start](quick-start.md): Build your first controller and contract. 2. **Controller Guide** * Learn about routing, HTTP decorators, dependency injection, exception filters, pagination, and OpenAPI schema generation. 3. **Contracts Guide** * Learn how to define schemas, declare facets, build projections, use lenses, and handle input validation and database imprinting.


---

## Framework Docs: docs/docs/tutorials/crud-api.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-crud-api`

--- title: "Full CRUD API Tutorial" description: "Step-by-step guide to building a complete CRUD API with Controllers and Contracts" icon: lucide/server ---In this tutorial, we will build a complete, production-grade **Product Catalog CRUD API** from scratch using Aquilia. You will learn how to declare schemas and persistence rules with **Contracts**, handle requests and configure routing using class-based **Controllers**, and apply advanced middleware behaviors such as pagination, declarative filtering, and rate limiting (throttling). --- Prerequisites Before starting, ensure you have: - Python 3.10 or higher installed. - A basic understanding of `async`/`await` in Python. - Aquilia installed in your local Python environment. --- What We're Building We are building a robust Product Catalog API. The system exposes the following REST endpoints: | Method | Endpoint | Description | | :--- | :--- | :--- | | `GET` | `/products` | List products (with pagination, filtering, and summary view) | | `GET` | `/products/{id}` | Retrieve details of a single product (with full view and computed fields) | | `POST` | `/products` | Create a new product (handles request casting, validation, and imprinting) | | `PUT` | `/products/{id}` | Update an existing product (partial save) | | `DELETE` | `/products/{id}` | Delete a product | --- Step 1: Define `ProductContract` A **Contract** is a first-class primitive in Aquilia that acts as a contract between your database models and the outside world. It governs both inbound data handling (casting, sealing, and imprinting) and outbound serialization (molding). !!! info 📎 [core.py:L826](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L826) First, let's assume a basic `Product` database model is declared in your application (using Aquilia's ORM or an integrated ORM): Now, define your `ProductContract` with field-level facets: Explaining the Mechanics 1. **`Spec` Configuration**: Configurations are declared in the inner `Spec` class. !!! warning Always name this inner class `Spec`. Using the traditional name `Meta` will raise a `ContractFault` during class compilation. 📎 [core.py:L305-309](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L305-L309) 2. **Projections**: Slicing the contract via subscript syntax (e.g., `ProductContract["summary"]`) extracts a restricted projection containing only selected facets. 📎 [core.py:L609-L624](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L609-L624) 3. **`DecimalFacet`**: Used for exact-precision currency representations to prevent float conversion rounding errors. 📎 [facets.py:L729-L784](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L729-L784) 4. **`Computed`**: A read-only facet populated on outbound rendering by calling a method on the contract or model. 📎 [facets.py:L1522-L1580](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/facets.py#L1522-L1580) --- Step 2: Define `ProductsController` Controllers provide a structured, class-based approach to request routing. Create a file named `controllers.py` and register the routing prefix: !!! info 📎 [base.py:L497](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/base.py#L497) The `prefix = "/products"` attribute prepends `/products` to all endpoint routes declared within this controller. --- Step 3: List Endpoint (GET `/`) To retrieve a list of products, append a handler to your controller class. We'll use the subscript reference `ProductContract["summary"]` to restrict the returned output to a concise format (showing only `id`, `name`, and `price`): !!! info By passing `ProductContract["summary"]` to `response_contract`, the framework automatically filters write-only fields and structures the response payload to match the `"summary"` projection. 📎 [http-decorators.mdx](../controller/http-decorators.md#L75-L77) --- Step 4: Retrieve Endpoint (GET `/{id:int}`) To retrieve detailed info about a single product, bind the route parameter `id` as an integer: The retrieve endpoint uses `ProductContract["detail"]` (which resolves to `__all__` fields plus the computed `discounted_price` facet). --- Step 5: Create Endpoint (POST `/`) For creation, we accept the request body, validate it against our contract schema, and save it to the database. This showcases the core inbound flow: **Cast → Seal → Imprint**. The Explicit Inbound Lifecycle When processing inbound payloads: 1. **Cast**: Raw request data is passed into the contract. Simple coercion is applied (e.g., matching string numbers to integers/decimals). 📎 [core.py:L1083-L1090](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/core.py#L1083-L1090) 2. **Seal**: Synchronous and asynchronous validation gates verify the coerced values. Calling `bp.is_sealed()` triggers this validation and seals the data container. 📎 [core.py:L1014](file:///Users/kuroyami/TuboxLabProject/aquilia-d

### Code Examples
```python
# models.py
from aquilia.db import Model, fields

class Product(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=255)
    description = fields.TextField()
    price = fields.DecimalField(max_digits=10, decimal_places=2)
    stock = fields.IntField()
    category = fields.CharField(max_length=100)

```

```python
# contracts.py
from aquilia.contracts import Contract
from aquilia.contracts.facets import TextFacet, IntFacet, DecimalFacet, Computed
from models import Product

class ProductContract(Contract):
    class Spec:
        model = Product
        fields = ["id", "name", "description", "price", "stock", "category"]
        projections = {
            "summary": ["id", "name", "price"],
            "detail": "__all__"
        }
        default_projection = "detail"

    # Define facets with explicit constraints
    name = TextFacet(required=True, min_length=3, max_length=100)
    description = TextFacet(required=False, default="")
    price = DecimalFacet(required=True, max_digits=10, decimal_places=2)
    stock = IntFacet(required=True, min_value=0)
    category = TextFacet(required=True)
    
    # A Computed facet is dynamically resolved during response serialization
    discounted_price = Computed("get_discounted_price")

    def get_discounted_price(self, product) -> str:
        """Applies a 10% discount to products priced over $100."""
        price = product.price
        if price > 100:
            return f"${(price * 0.9):.2f}"
        return f"${price:.2f}"

```

```python
# controllers.py
from aquilia import Controller

class ProductsController(Controller):
    prefix = "/products"
    tags = ["products"]

```



---

## Framework Docs: docs/docs/tutorials/content-negotiation.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-content-negotiation`

--- title: "Content Negotiation Tutorial" description: "Serving multiple response formats (JSON, XML, CSV) dynamically based on Accept headers or query params" icon: lucide/shuffle ---In this tutorial, we will walk through how to build a flexible API endpoint in Aquilia that can serve the same product data as JSON, XML, or CSV. We will leverage Aquilia's built-in content negotiation system and extend it with a custom CSV renderer. Prerequisites Before starting, ensure you have read the primary documentation on [Content Negotiation & Renderers](../controller/renderers.md) to understand how the [ContentNegotiator](../controller/renderers.md#L129) and [BaseRenderer](../controller/renderers.md#L50-L80) operate. --- Step 1: JSONRenderer + XMLRenderer on ProductsController By default, Aquilia controllers use [JSONRenderer](../controller/renderers.md#L23) as the fallback. To support both JSON and XML on your controller, import and register both [JSONRenderer](../controller/renderers.md#L23) and [XMLRenderer](../controller/renderers.md#L24) in the controller's `renderer_classes` attribute. Create your controller file with the following setup (modeled after the [Multi-format API Endpoint example](../controller/renderers.md#L316-L352)): !!! info The order of `renderer_classes` defines the priority list. If a client's `Accept` header contains `*/*` or is missing, the negotiator falls back to the first renderer in the list, which is [JSONRenderer](../controller/renderers.md#L23) in this setup (see [Negotiation Priority](../controller/renderers.md#L32-L48)). --- Step 2: Testing with Accept Header With both renderers registered, the [ContentNegotiator](../controller/renderers.md#L129) evaluates incoming `Accept` headers to select the best match based on client preferences (quality factors). Test 1: Requesting XML Send an HTTP request with the `Accept: application/xml` header (as detailed in [Quality Factor Negotiation](../controller/renderers.md#L403-L418)): **Response Content-Type:** `application/xml; charset=utf-8` **Response Body:** Test 2: Requesting JSON (Default Fallback) If no `Accept` header or a wildcard is sent: **Response Content-Type:** `application/json; charset=utf-8` **Response Body:** --- Step 3: ?format=xml Query Parameter Override Sometimes, browser clients or developers testing in a browser cannot easily manipulate the `Accept` headers. Aquilia provides a built-in query parameter override `?format=` which takes highest priority over headers (proven in [Negotiation Priority](../controller/renderers.md#L32-L48)). For example, to explicitly request XML format via the URL query parameters: The negotiator checks the value of `?format=` against each renderer's `format_suffix` (which is `"xml"` for [XMLRenderer](../controller/renderers.md#L24) and `"json"` for [JSONRenderer](../controller/renderers.md#L23)). !!! warning If you pass an invalid format suffix like `?format=invalid`, the negotiator will bypass the parameter and fall back to evaluating the `Accept` header or using the default renderer. --- Step 4: Writing a Custom CSVRenderer To support exporting data to CSV format, we can write a custom renderer by subclassing [BaseRenderer](../controller/renderers.md#L50-L80) and implementing the abstract `render` method (as shown in [Custom Renderer](../controller/renderers.md#L242-L282)). Create `renderers.py` and write the custom class: Verification details: - **media_type**: `"text/csv"` matches the standard MIME type. - **format_suffix**: `"csv"` matches standard query params overrides (`?format=csv`). - **render**: Signature conforms exactly to [BaseRenderer.render](../controller/renderers.md#L62-L71). --- Step 5: Registering CSVRenderer We can register `CSVRenderer` at two levels: controller level (applying to all routes on the controller) and route level (applying only to a specific route via manual negotiation). Option A: Controller-Level Registration Add the renderer class directly to the list of `renderer_classes` on the controller (see [Controller-level renderer_classes](../controller/renderers.md#L111-L130)): Test controller-level CSV selection: Option B: Route-Level Registration & Manual Negotiation If you only want specific endpoints to allow CSV downloads, keep the controller class clean and manually invoke [negotiate](../controller/renderers.md#L166-L201) (modeled after [Route-level Override](../controller/renderers.md#L131-L165)): !!! info By invoking [negotiate](../controller/renderers.md#L166-L201) manually, the controller returns the pre-rendered string/bytes body directly. Be sure to set the `Content-Type` header from `content_type` so the client knows how to parse the result.

### Code Examples
```python
from aquilia import Controller, GET
from aquilia.controller.renderers import JSONRenderer, XMLRenderer

class ProductsController(Controller):
    prefix = "/products"
    
    # Registering built-in renderers. Order determines default fallback (JSON)
    renderer_classes = [
        JSONRenderer(indent=2),
        XMLRenderer(root_tag="products", item_tag="product")
    ]
    
    @GET("/")
    async def list_products(self, ctx):
        # Return Python dict/list structures directly; Aquilia handles translation.
        return [
            {"id": 1, "name": "Widget", "price": 9.99},
            {"id": 2, "name": "Gadget", "price": 19.99},
        ]

```

```python
curl -H "Accept: application/xml" http://localhost:8000/products

```

```python
xml
<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product>
    <id>1</id>
    <name>Widget</name>
    <price>9.99</price>
  </product>
  <product>
    <id>2</id>
    <name>Gadget</name>
    <price>19.99</price>
  </product>
</products>

```



---

## Framework Docs: docs/docs/tutorials/rate-limiting.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-rate-limiting`

--- title: "Rate Limiting & Interceptors Tutorial" description: "Configuring request throttles, custom interceptors, and exception filters" icon: lucide/gauge ---In this tutorial, you will learn how to configure rate limiting (throttling), track request performance, log lifecycle events, and handle throttle exceptions gracefully in Aquilia. We will build an API controller step-by-step to demonstrate how these pieces interact within the Aquilia controller pipeline. --- Prerequisites Ensure you have imported the core components of the Aquilia framework. We will build a controller for managing item resources: --- Step 1: Controller-Level Throttling Aquilia provides a sliding-window in-memory rate limiter using the `Throttle` class. You can apply a default rate limit across all endpoints in a controller by defining the `throttle` class attribute. Add a default rate limit of 100 requests per 60 seconds: !!! info **API Verification & Evidence:** As defined in [throttle.mdx](../controller/throttle.md#L133-L157), setting the `throttle` class attribute enforces the rate limiter automatically across all controller handler methods. The sliding-window algorithm isolates clients by resolving their IP addresses. --- Step 2: Per-Route Throttle Override You can customize or entirely disable rate limits for individual routes using the `throttle` parameter directly inside route decorators. Let's add a strict limit on creation requests (5 requests per 60 seconds) and disable throttling completely for health checks: !!! info **API Verification & Evidence:** Route-level overriding is documented in [throttle.mdx](../controller/throttle.md#L159-L223). A route-level `throttle` attribute takes precedence over the controller's default `throttle`. Passing `throttle=None` excludes the route from any checks. --- Step 3: Request Performance Timing Interceptor Interceptors wrap handler execution with before/after logic. We can use a custom interceptor to measure the exact execution duration of a request using `time.perf_counter()` and store the start timestamp in `ctx.state`. !!! info **API Verification & Evidence:** As documented in [interceptors.mdx](../controller/interceptors.md#L155-L191), the `before` hook runs before handler execution and allows initializing request-scoped state in `ctx.state`. The `after` hook intercepts and transforms the returned result before sending the response. --- Step 4: Request/Response Logging Interceptor Now let's add a second custom interceptor that logs the lifecycle of every incoming request and outgoing response, utilizing the request ID for tracing. !!! info **API Verification & Evidence:** `ctx.request_id`, `ctx.method`, and `ctx.path` are standard, documented properties on `RequestCtx`. As shown in [interceptors.mdx](../controller/interceptors.md#L192-L213), class-level interceptors are registered in the order they appear and execute sequentially. --- Step 5: Rate Limit Exception Filter When doing manual rate limiting or using native faults, you want to return a clean JSON payload and appropriate headers (like `Retry-After`). Let's define a custom exception `ThrottleExceeded` for manual throttling checks, and write exception filters to handle both the custom exception and native Aquilia rate-limiting faults (`RateLimitExceededFault` and `TooManyRequestsFault`). Custom Exception & Exception Filter Complete Controller Assembly Register the interceptors and exception filters at the class level: !!! info **API Verification & Evidence:** Class-level registration of exception filters is documented in [exception-filters.mdx](../controller/exception-filters.md#L51-L62). The engine matches thrown exceptions against the filters' `catches` definitions sequentially ([exception-filters.mdx](../controller/exception-filters.md#L126-L152)). --- Step 6: Testing with curl You can verify the rate limiting, interceptors, and exception filters using `curl`. 1. Test Controller-Level Throttling & Timing Request the default route to verify the timing interceptor output: **Success Response (includes timing information):** Check your application console logs to see the output from the `LoggingInterceptor`: 2. Test Per-Route Throttle Override Make repeated requests to the stricter route (which has a limit of 5 requests/minute): **Throttled Response (6th request):** 3. Test Manual Throttling and Custom Exception Filter Make repeated requests to the manual endpoint (which permits only 2 requests per 10 seconds): **Throttled Response (3rd request, caught by exception filter):**

### Code Examples
```python
from aquilia.controller import Controller, Throttle, Interceptor, ExceptionFilter
from aquilia.decorators import GET, POST
from aquilia.response import Response

```

```python
class ItemsController(Controller):
    prefix = "/items"
    
    # Class-level rate limiting: 100 requests per 60 seconds
    throttle = Throttle(limit=100, window=60)

    @GET("/")
    async def list_items(self, ctx):
        # Inherits the controller-level throttle (100 reqs / 60s)
        return {"items": ["Item A", "Item B"]}

```

```python
class ItemsController(Controller):
    prefix = "/items"
    throttle = Throttle(limit=100, window=60)

    @GET("/")
    async def list_items(self, ctx):
        return {"items": ["Item A", "Item B"]}

    # Route-level override: Stricter limit for POST requests
    @POST("/", throttle=Throttle(limit=5, window=60))
    async def create_item(self, ctx):
        data = await ctx.json()
        return {"status": "created", "item": data}

    # Route-level override: Completely bypass rate limiting
    @GET("/health", throttle=None)
    async def health(self, ctx):
        return {"status": "ok"}

```



---

## Framework Docs: docs/docs/tutorials/nested-resources.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-nested-resources`

--- title: "Nested Resources & Lenses Tutorial" description: "How to use Lenses and Projections to model and serialize nested relations" icon: lucide/folder-tree ---In modern REST and GraphQL APIs, resources rarely exist in isolation. An order contains items, which reference products; it also belongs to a customer, who has a billing profile. Serializing and validating these deeply nested object graphs while avoiding N+1 query problems, infinite recursion, and over-fetching is a classic engineering challenge. Aquilia solves this elegantly using two unified primitives: 1. **Lenses**: Optical relational facets that focus on and traverse related data models ([lenses.py:L7-10](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L7-L10)). 2. **Projections**: Tailored, named subsets of fields configured on the contract itself, allowing routes to request different levels of detail ([projections.py:L4-6](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L4-L6)). In this tutorial, you will learn how to design schemas for nested relations, customize exposed data via projections, and manage depth limits and circular references. --- Scenario: The E-Commerce Order System We will build a nested serialization setup for an e-commerce order system with the following relationship graph: Our database models are defined as follows: - **`Customer`**: A user with `id`, `name`, and a sensitive `email` address. - **`OrderItem`**: A line item on an order, consisting of `id`, `product_name`, `quantity`, and `price`. - **`Order`**: The root transaction record, containing `id`, `created_at`, a customer relationship, and a collection of order items. --- Step 1: Define the CustomerContract First, we will define a contract for the `Customer` model. We want to expose the customer's ID and name publicly, but restrict access to their email address unless explicitly requested (e.g., in a detail or admin view). To do this, we configure named **projections** inside the inner `Spec` class ([projections.py:L30-38](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L30-L38)): !!! info By using `default_projection = "public"`, any serialization of a customer instance via `CustomerContract` will automatically exclude the `email` field unless the `"detail"` projection is explicitly selected ([projections.py:L109](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L109)). --- Step 2: Define the OrderItemContract Next, we define the `OrderItemContract`. This represents the line items stored in our database. --- Step 3: Define the OrderContract with Lenses Now, we define our root `OrderContract`. To embed the customer details and the collection of order items, we use the `Lens` facet ([lenses.py:L26](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L26)). A `Lens` acts as an optical focus on related data. It can target a raw `Contract` or a subscripted projection class: Let's break down the `Lens` configuration: - **`CustomerContract["public"]`**: By subscripting `CustomerContract` with `"public"`, we create a `_ProjectedRef` ([lenses.py:L187-201](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L187-L201)). The lens automatically extracts this and configures the nested customer data to strictly use the public projection ([lenses.py:L65-70](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L65-L70)). - **`OrderItemContract` & `many=True`**: When `many=True` is provided, the lens expects an iterable sequence of records and runs the molding logic on each record ([lenses.py:L56](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L56)). - **`source`**: The model attribute path to extract the relation data from ([lenses.py:L59](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L59)). If omitted, Aquilia's `bind()` method will attempt to auto-resolve relationship field mappings directly from the database model specs ([lenses.py:L79-91](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/lenses.py#L79-L91)). --- Step 4: ProjectionRegistry — Summary vs. Detail Every `Contract` class is backed by a `ProjectionRegistry` ([projections.py:L26-28](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L26-L28)). The registry compiles the projection definitions during class construction ([projections.py:L58-109](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L58-L109)). When serializing an instance via `.data` or `to_dict()`, the active projection resolves to a frozen set of facet names ([projections.py:L111-132](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/contracts/projections.py#L111-L132)), controlling which attributes are included: 1. **`summary` Projection**: Includes only `"id"`, `"cr

### Code Examples
```python
mermaid
graph TD
    Order[Order] -->|One-to-One Lens| Customer[Customer]
    Order -->|One-to-Many Lens| OrderItem[OrderItem]

```

```python
from aquilia.contracts import Contract

class CustomerContract(Contract):
    class Spec:
        model = Customer
        # Define named subsets of facets
        projections = {
            "public": ["id", "name"],
            "detail": "__all__"  # Resolves to all non-write-only facets (projections.py:L42)
        }
        # Fall back to "public" if no projection is explicitly requested
        default_projection = "public"

    id: int
    name: str
    email: str

```

```python
from aquilia.contracts import Contract

class OrderItemContract(Contract):
    class Spec:
        model = OrderItem
        fields = ["id", "product_name", "quantity", "price"]

    id: int
    product_name: str
    quantity: int
    price: float

```



---

## Framework Docs: docs/docs/tutorials/openapi-setup.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-openapi-setup`

--- title: "Auto OpenAPI Setup Tutorial" description: "Generating and serving interactive Swagger UI and ReDoc pages automatically from controllers" icon: lucide/workflow ---Serving interactive API documentation directly from your web application improves developer experience and ensures your API specifications remain in sync with your actual backend logic. Aquilia offers robust built-in support for generating OpenAPI 3.1.0 specifications by introspecting your controllers, routes, guards, and type hints. This tutorial guides you through configuring, generating, and serving **Swagger UI** and **ReDoc** documentation interfaces inside an Aquilia app. --- Step 1: OpenAPIConfig Setup The first step in generating documentation is defining your API's metadata and serving paths using [OpenAPIConfig](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578) (defined in [openapi.py:L578-L633](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L578-L633)). You can instantiate this configuration class with your API's basic details: !!! info By default, `OpenAPIConfig` serves Swagger UI at `/docs`, ReDoc at `/redoc`, and the raw specification at `/openapi.json` (as documented in [openapi.py:L72-L86](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L72-L86)). --- Step 2: Generate Specification with `OpenAPIGenerator` The [OpenAPIGenerator](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L638) class (defined in [openapi.py:L638-L961](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L638-L961)) is the core compiler. It scans an active [ControllerRouter](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/router.py) and compiles all route definitions into a compliant OpenAPI 3.1.0 schema dictionary. Pass your `OpenAPIConfig` to the generator and call `generate()`: The returned `openapi_spec` is a dictionary conforming to the OpenAPI 3.1.0 standard, complete with `paths`, `components`, `tags`, and `security` mappings (documented in [openapi.py:L711-L755](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L711-L755)). --- Step 3: Mount Routes to Serve Swagger UI Aquilia provides [generate_swagger_html()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L1027) (defined in [openapi.py:L1027-L1055](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L1027-L1055)) to render a complete HTML page including Swagger UI Javascript and CSS fetched from high-speed CDNs. To serve this page, set up a route inside a documentation controller: > [!TIP] > You can toggle a sleek dark theme easily by setting `swagger_ui_theme="dark"` inside `OpenAPIConfig` ([openapi.py:L122-L125](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L122-L125)). --- Step 4: Mount Routes to Serve ReDoc Similarly, Aquilia offers a minimalist, multi-panel documentation style via [generate_redoc_html()](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L1084) (defined in [openapi.py:L1084-L1089](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L1084-L1089)). Mount it under your configured `redoc_path`: --- Step 5: Enriching Endpoints with Metadata You can customize how your endpoints look and group in the interactive UIs by supplying docstrings and route metadata parameters: 1. **Summary & Description**: The generator looks at the route's explicit metadata or parses the handler's docstrings (as shown in [openapi.py:L846-L847](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L846-L847)). The first line maps to the **Summary**, and the remaining lines map to the **Description**. 2. **Tags**: Organize operations into sections. The generator fallbacks from route-level `route_meta.tags` to controller-level `tags` class properties (documented in [openapi.py:L858-L863](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L858-L863)). 3. **Deprecated**: Mark routes as outdated or retired using the `deprecated=True` attribute inside the route handler parameters or metadata. --- Step 6: `request_contract` and `response_contract` Usage To enforce structure validation and compile precise JSON schemas automatically, you can explicitly configure `request_contract` and `response_contract` within your route decorators. Rather than relying purely on docstring comments, using request and response contracts allows the `OpenAPIGenerator` to parse class properties directly and populate schema structures under `components/schemas` (similar to standard dataclass translation described in [openapi.py:L486-L491](file:///Users/kuroyami/TuboxLabProject/aquilia-docs/aquilia/controller/openapi.py#L486-L491)). --- Complete Documentation Controller Example Below is a complet

### Code Examples
```python
from aquilia.controller.openapi import OpenAPIConfig

config = OpenAPIConfig(
    title="Aquilia Application API",
    version="1.0.0",
    description="Comprehensive developer documentation for the Aquilia backend application services.",
    docs_path="/docs",                  # Swagger UI location
    openapi_json_path="/openapi.json",  # Raw JSON specification location
    redoc_path="/redoc"                 # ReDoc UI location
)

```

```python
from aquilia.controller.openapi import OpenAPIGenerator
from aquilia.controller.router import ControllerRouter

# Initialize the compiler
generator = OpenAPIGenerator(config=config)

# Compile controller routes to OpenAPI spec format
# router should be your application's ControllerRouter instance
openapi_spec = generator.generate(router)

```

```python
from aquilia.controller import Controller, GET, Response
from aquilia.controller.openapi import generate_swagger_html

class DocsController(Controller):
    # ... setup controller initialization with config

    @GET("/")
    async def get_swagger_ui(self):
        """Render the interactive Swagger UI console."""
        html = generate_swagger_html(self.config)
        return Response.html(html)

```



---

## Framework Docs: docs/docs/tutorials/filtering-pagination.md
**URL**: `https://tubox.cloud/docs/framework/docs-docs-tutorials-filtering-pagination`

--- title: "Filtering, Search & Pagination Tutorial" description: "How to configure complex list endpoints with search, ordering, filter backends, and pagination" icon: lucide/sliders ---Add search, filter, and pagination to a list endpoint This tutorial guides you through adding search, filtering, sorting, and pagination to an API list endpoint using Aquilia. You will learn how to configure these features both individually and combined into a single, high-performance route handler. Scenario: Product Catalog with 10,000 Products Imagine you are building a product listing API. Your database has **10,000 products** spanning multiple categories, prices, and creation dates. Returning all 10,000 products in a single request would: - Degrade database and network performance. - Overwhelm client applications. - Cause high memory usage on the server. To solve this, we will implement filtering, search, ordering, and pagination step-by-step. --- Step 1: FilterSet with Price Range & Category Exact `FilterSet` provides declarative field-based filtering. We will configure a `ProductFilter` that allows users to filter by category (exact match) and price (greater than or equal, less than or equal, or a range). How It Works - **Category Filter**: Matches the category exactly. Query: `GET /products?category=electronics` - **Price Filters**: - `price__gte=50` (Greater than or equal to 50) - `price__lte=150` (Less than or equal to 150) - `price__range=50,150` (Between 50 and 150, comma-separated list value) > [!NOTE] > According to the **[Filtering Documentation](../controller/filtering.md#L42-L135)**, Aquilia automatically coerces query string values into their correct Python types, such as converting comma-separated values to lists for `range` lookups and strings to floats for numeric queries. --- Step 2: Adding search_fields for Name + Description Often, users need a free-text search across multiple fields instead of strict filters. Aquilia provides the `search_fields` parameter on the route decorator to enable case-insensitive text search. We will configure search to look up keywords in the `name` and `description` fields: Behavior - When a client sends `?search=wireless`, Aquilia builds an `OR` query under the hood: `name__icontains="wireless" | description__icontains="wireless"` - An item is returned if the term matches **any** of the configured search fields. > [!NOTE] > As described in the **[SearchFilter documentation](../controller/filtering.md#L185-L254)**, text search handles both ORM querysets (building `QNode` OR chains) and in-memory lists (case-insensitive substring checks) seamlessly. --- Step 3: Configuring ordering_fields for Price & Created At Users expect to sort lists by relevant columns like cheapest price or newest products. `OrderingFilter` enables dynamic field ordering based on the `?ordering` query parameter. We will whitelist `price` and `created_at` for ordering: Query Syntax - **Ascending**: `GET /products?ordering=price` (sorts cheapest first) - **Descending**: `GET /products?ordering=-price` (sorts most expensive first, using the `-` prefix) - **Multiple fields**: `GET /products?ordering=-created_at,price` (newest first, then by price ascending) > [!IMPORTANT] > As shown in the **[OrderingFilter security section](../controller/filtering.md#L277-L290)**, only fields present in `ordering_fields` are allowed. Arbitrary query fields are ignored to prevent database index abuse or exposure of hidden fields. --- Step 4: PageNumberPagination (page + page_size) For a classic paginated interface (e.g., desktop search results with `[1] [2] [3] ... [Next]`), `PageNumberPagination` is the default approach. We can define a custom pagination class: Query Parameters - `page` (default: `1`) - `page_size` (default: `20`, client can increase it up to `100`) Response Envelope The response is automatically wrapped in a structured metadata object (see **[PageNumberPagination Response Envelope](../controller/pagination.md#L47-L68)**): --- Step 5: LimitOffsetPagination (limit + offset) For developers preferred to SQL-style syntax (`LIMIT 20 OFFSET 40`), `LimitOffsetPagination` is ideal. Query Parameters - `limit` (default: `20`) - `offset` (default: `0`) Response Envelope This envelope omits absolute page numbers but details exact slices (see **[LimitOffsetPagination Response Envelope](../controller/pagination.md#L106-L124)**): --- Step 6: CursorPagination (Keyset for Infinite Scroll) When dealing with a dynamic catalog of 10,000 products, offset-based pagination (Steps 4 & 5) suffers from two major limitations: 1. **Performance**: Large offsets (e.g. `OFFSET 9980`) require database engines to scan and discard rows, leading to slow response times. 2. **Duplicate Items**: If a new product is added to the database while a user is scrolling, items shift pages, causing duplicates to appear. `CursorPagination` solves this by using keyset pagination: filtering queries by the unique ordering value (e.g. `WHERE id < last_seen

### Code Examples
```python
from aquilia import FilterSet

class ProductFilter(FilterSet):
    class Meta:
        fields = {
            "category": ["exact"],
            "price": ["gte", "lte", "range"],
        }

```

```python
# Decorator configuration:
search_fields=["name", "description"]

```

```python
# Decorator configuration:
ordering_fields=["price", "created_at"]

```



---

## Framework Docs: docs/i18n/examples.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-examples`

<!-- Legacy mirror. Canonical page: ../modules/i18n/examples.md --> I18N Examples Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Examples here use public symbols and checked patterns from the repository. When a module has no safe standalone constructor example, the example focuses on importing and wiring the actual source-backed API. Source-Backed Import Examples Workspace/Manifest Wiring Example Verification - Run `python -m aquilia.cli.__main__ --help` to confirm CLI availability. - Run `aq validate` in a workspace to validate manifest paths. - Run related tests under `tests/` or `examples/*/tests/` for executable behavior.

### Code Examples
```python
from aquilia.i18n.catalog import TranslationCatalog
from aquilia.i18n.catalog import MemoryCatalog
from aquilia.i18n.catalog import has_surp
from aquilia.i18n.di_integration import register_i18n_providers
from aquilia.i18n.faults import I18nFault
from aquilia.i18n.faults import MissingTranslationFault

```

```python
from aquilia import AppManifest, Integration, Module, Workspace

workspace = (
    Workspace("example", version="1.0.0")
    .runtime(mode="dev", port=8000)
    .module(Module("example").route_prefix("/example"))
    .integrate(Integration.di(auto_wire=True))
)

manifest = AppManifest(
    name="example",
    version="1.0.0",
    controllers=["modules.example.controllers:ExampleController"],
    services=["modules.example.services:ExampleService"],
)

```



---

## Framework Docs: docs/i18n/architecture.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-architecture`

<!-- Legacy mirror. Canonical page: ../modules/i18n/architecture.md --> I18N Architecture Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Source Boundaries | File | Lines | Classes | Functions | Purpose | | --- | ---: | ---: | ---: | --- | | `aquilia/i18n/__init__.py` | 182 | 0 | 0 | AquilaI18n — Industry-grade Internationalization & Localization for Aquilia. | | `aquilia/i18n/catalog.py` | 810 | 6 | 1 | Translation Catalogs — Storage and retrieval of translation strings. | | `aquilia/i18n/di_integration.py` | 183 | 0 | 2 | I18n DI Integration — Register i18n providers in Aquilia's DI container. | | `aquilia/i18n/faults.py` | 187 | 5 | 0 | I18n Faults — Typed fault signals for the i18n subsystem. | | `aquilia/i18n/formatter.py` | 627 | 1 | 9 | Message Formatter — ICU MessageFormat-inspired interpolation & locale formatting. | | `aquilia/i18n/lazy.py` | 289 | 2 | 4 | Lazy Strings — Deferred translation resolution. | | `aquilia/i18n/locale.py` | 352 | 1 | 5 | Locale — BCP 47 locale tag parsing, normalization, and negotiation. | | `aquilia/i18n/middleware.py` | 423 | 8 | 1 | I18n Middleware — Request-scoped locale resolution & injection. | | `aquilia/i18n/plural.py` | 515 | 1 | 2 | Plural Rules — CLDR-based plural category selection for 200+ languages. | | `aquilia/i18n/service.py` | 425 | 3 | 1 | I18n Service — Central orchestrator for all translation operations. | | `aquilia/i18n/template_integration.py` | 197 | 1 | 1 | I18n Template Integration — Jinja2 globals, filters, and extensions. | Internal Shape `i18n` has 11 Python files, 28 public classes, 26 public module-level functions, and 12 constants or module flags detected by AST. Runtime Responsibilities - This module has `aq` command coverage documented in `cli-reference.md`; 6 commands map to this subsystem. Internal Imports | Import | Count | | --- | ---: | | `.locale` | 3 | | `.plural` | 3 | | `.catalog` | 2 | | `.formatter` | 2 | | `.lazy` | 2 | | `.di_integration` | 1 | | `.faults` | 1 | | `.middleware` | 1 | | `.service` | 1 | | `.template_integration` | 1 | | `aquilia._version` | 1 | | `aquilia.faults.core` | 1 | External And Stdlib Imports | Import root | Count | | --- | ---: | | `__future__` | 10 | | `typing` | 8 | | `logging` | 5 | | `collections` | 4 | | `abc` | 2 | | `dataclasses` | 2 | | `datetime` | 2 | | `enum` | 2 | | `pathlib` | 2 | | `re` | 2 | | `contextvars` | 1 | | `decimal` | 1 | | `hashlib` | 1 | | `json` | 1 | Lifecycle And Extension Points | Extension Type | Source | Role | | --- | --- | --- | | `I18nMiddleware` | `aquilia/i18n/middleware.py` | Aquilia middleware that resolves locale and injects i18n into requests. | | `I18nConfig` | `aquilia/i18n/service.py` | Configuration for the i18n service. | Error Handling Fault/error classes defined here: `I18nFault`, `MissingTranslationFault`, `InvalidLocaleFault`, `CatalogLoadFault`, `PluralRuleFault`


---

## Framework Docs: docs/i18n/troubleshooting.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-troubleshooting`

<!-- Legacy mirror. Canonical page: ../modules/i18n/troubleshooting.md --> I18N Troubleshooting Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Fast Diagnosis Flow 1. Confirm the command is run from a directory containing `workspace.py` unless it is help/version/init/doctor. 2. Run `aq doctor` for workspace, environment, registry, integration, and deployment checks. 3. Run `aq validate` to catch manifest errors. 4. Run `aq inspect config` to inspect resolved settings. 5. Run `aq inspect modules` and `aq inspect routes` when discovery or routing is suspect. 6. Check `api-reference.md` for exact public API signatures. Module-Relevant Commands - `aq i18n init` - `aq i18n check` - `aq i18n inspect` - `aq i18n extract` - `aq i18n coverage` - `aq i18n compile` Symptoms And Actions | Symptom | Likely Source | Action | | --- | --- | --- | | Import error during startup | Bad manifest class path or optional provider dependency | Check `modules/<name>/manifest.py`, install the relevant extra, and rerun `aq validate`. | | Route not found | Controller omitted from manifest, wrong route prefix, or startup conflict | Run `aq inspect routes`; inspect controller decorators and `Module.route_prefix()`. | | Dependency not found | Service not registered or constructor annotation cannot be resolved | Check `AppManifest.services`, DI provider registrations, and `aq inspect di`. | | Config value missing | Dotenv/env overlay not loaded or wrong nested key | Check `ConfigLoader` precedence and `AQ_` double-underscore key names. | | Production security failure | Insecure secret or required key not configured | Set `AQ_SECRET_KEY`, `SECRET_KEY`, or Python-native secret config. | | Optional subsystem unavailable | Provider/backend dependency or startup connection failed | Check startup logs; optional subsystems often log non-fatal failures. | Source Files To Inspect | File | Lines | Public classes | Public functions | Purpose | | --- | ---: | ---: | ---: | --- | | `aquilia/i18n/__init__.py` | 182 | 0 | 0 | AquilaI18n — Industry-grade Internationalization & Localization for Aquilia. | | `aquilia/i18n/catalog.py` | 810 | 6 | 1 | Translation Catalogs — Storage and retrieval of translation strings. | | `aquilia/i18n/di_integration.py` | 183 | 0 | 2 | I18n DI Integration — Register i18n providers in Aquilia's DI container. | | `aquilia/i18n/faults.py` | 187 | 5 | 0 | I18n Faults — Typed fault signals for the i18n subsystem. | | `aquilia/i18n/formatter.py` | 627 | 1 | 9 | Message Formatter — ICU MessageFormat-inspired interpolation & locale formatting. | | `aquilia/i18n/lazy.py` | 289 | 2 | 4 | Lazy Strings — Deferred translation resolution. | | `aquilia/i18n/locale.py` | 352 | 1 | 5 | Locale — BCP 47 locale tag parsing, normalization, and negotiation. | | `aquilia/i18n/middleware.py` | 423 | 8 | 1 | I18n Middleware — Request-scoped locale resolution & injection. | | `aquilia/i18n/plural.py` | 515 | 1 | 2 | Plural Rules — CLDR-based plural category selection for 200+ languages. | | `aquilia/i18n/service.py` | 425 | 3 | 1 | I18n Service — Central orchestrator for all translation operations. | | `aquilia/i18n/template_integration.py` | 197 | 1 | 1 | I18n Template Integration — Jinja2 globals, filters, and extensions. |


---

## Framework Docs: docs/i18n/edge-cases-and-limitations.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-edge-cases-and-limitations`

<!-- Legacy mirror. Canonical page: ../modules/i18n/edge-cases-and-limitations.md --> I18N Edge Cases And Limitations Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Source-Backed Limits - No module-specific edge branch was detected beyond optional imports, validation, and dependency availability. Fault And Error Classes Detected `I18nFault`, `MissingTranslationFault`, `InvalidLocaleFault`, `CatalogLoadFault`, `PluralRuleFault` Operational Boundaries - Optional external libraries are only required when the corresponding provider/backend/runtime is configured. - Deprecated APIs generally warn when retained for migration rather than disappearing silently. - Server startup intentionally degrades non-critical optional subsystems where source catches and logs exceptions. - Use `api-reference.md` to check exact constructor defaults and method signatures before depending on behavior. Verification - `aq doctor` for workspace/integration issues. - `aq validate` for manifest issues. - `aq inspect config` for merged configuration. - `GET /_health` for live subsystem status once the app is running.


---

## Framework Docs: docs/i18n/integration-guide.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-integration-guide`

<!-- Legacy mirror. Canonical page: ../modules/i18n/integration-guide.md --> I18N Integration Guide Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Where This Module Fits Configure this subsystem through the matching `Integration.*(...)` builder when available, or through typed classes in `aquilia.integrations`. Manifest Pattern Verification - `aq validate` checks manifest structure. - `aq doctor` runs broader workspace diagnostics. - `aq inspect config` shows resolved configuration. - `aq inspect routes` shows compiled HTTP routes after discovery/compilation.

### Code Examples
```python
from aquilia import AppManifest

manifest = AppManifest(
    name="example",
    version="1.0.0",
    controllers=["modules.example.controllers:ExampleController"],
    services=["modules.example.services:ExampleService"],
)

```



---

## Framework Docs: docs/i18n/README.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-README`

<!-- Legacy mirror. Canonical page: ../modules/i18n/README.md --> I18N Documentation Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. Coverage Snapshot - Source files: 11 - Source lines: 4190 - Public classes: 28 - Public module functions: 26 - Constants/module flags: 12 - Public exports in `__all__`: 50 Source Files Read - `aquilia/i18n/__init__.py`: AquilaI18n — Industry-grade Internationalization & Localization for Aquilia. - `aquilia/i18n/catalog.py`: Translation Catalogs — Storage and retrieval of translation strings. - `aquilia/i18n/di_integration.py`: I18n DI Integration — Register i18n providers in Aquilia's DI container. - `aquilia/i18n/faults.py`: I18n Faults — Typed fault signals for the i18n subsystem. - `aquilia/i18n/formatter.py`: Message Formatter — ICU MessageFormat-inspired interpolation & locale formatting. - `aquilia/i18n/lazy.py`: Lazy Strings — Deferred translation resolution. - `aquilia/i18n/locale.py`: Locale — BCP 47 locale tag parsing, normalization, and negotiation. - `aquilia/i18n/middleware.py`: I18n Middleware — Request-scoped locale resolution & injection. - `aquilia/i18n/plural.py`: Plural Rules — CLDR-based plural category selection for 200+ languages. - `aquilia/i18n/service.py`: I18n Service — Central orchestrator for all translation operations. - `aquilia/i18n/template_integration.py`: I18n Template Integration — Jinja2 globals, filters, and extensions. Document Map - `architecture.md`: module boundaries, dependencies, lifecycle, and extension points. - `configuration.md`: configuration classes, builders, server wiring, and precedence. - `api-reference.md`: source-extracted classes, methods, functions, constants, exports, and signatures. - `integration-guide.md`: how to wire the module into an Aquilia app. - `cli-reference.md`: mounted `aq` commands for this module, if any. - `examples.md`: usage examples derived from source and checked example apps. - `edge-cases-and-limitations.md`: implementation limits and compatibility behavior. - `troubleshooting.md`: diagnostic commands and common failure patterns.


---

## Framework Docs: docs/i18n/configuration.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-configuration`

<!-- Legacy mirror. Canonical page: ../modules/i18n/configuration.md --> I18N Configuration Internationalization service, locale negotiation, catalogs, formatting, plural rules, lazy strings, middleware, CLI helpers, and template integration. This page distinguishes direct configuration APIs from indirect runtime wiring. All class names and source files below are extracted from the current source tree. Configuration Model This module exposes config-oriented public classes. Use the table below to locate exact constructors and `to_dict()` behavior in `api-reference.md`. Source Inventory | File | Lines | Public classes | Public functions | Purpose | | --- | ---: | ---: | ---: | --- | | `aquilia/i18n/__init__.py` | 182 | 0 | 0 | AquilaI18n — Industry-grade Internationalization & Localization for Aquilia. | | `aquilia/i18n/catalog.py` | 810 | 6 | 1 | Translation Catalogs — Storage and retrieval of translation strings. | | `aquilia/i18n/di_integration.py` | 183 | 0 | 2 | I18n DI Integration — Register i18n providers in Aquilia's DI container. | | `aquilia/i18n/faults.py` | 187 | 5 | 0 | I18n Faults — Typed fault signals for the i18n subsystem. | | `aquilia/i18n/formatter.py` | 627 | 1 | 9 | Message Formatter — ICU MessageFormat-inspired interpolation & locale formatting. | | `aquilia/i18n/lazy.py` | 289 | 2 | 4 | Lazy Strings — Deferred translation resolution. | | `aquilia/i18n/locale.py` | 352 | 1 | 5 | Locale — BCP 47 locale tag parsing, normalization, and negotiation. | | `aquilia/i18n/middleware.py` | 423 | 8 | 1 | I18n Middleware — Request-scoped locale resolution & injection. | | `aquilia/i18n/plural.py` | 515 | 1 | 2 | Plural Rules — CLDR-based plural category selection for 200+ languages. | | `aquilia/i18n/service.py` | 425 | 3 | 1 | I18n Service — Central orchestrator for all translation operations. | | `aquilia/i18n/template_integration.py` | 197 | 1 | 1 | I18n Template Integration — Jinja2 globals, filters, and extensions. | Detected Config-Oriented Classes | Class | Source | Methods | Summary | | --- | --- | --- | --- | | `I18nMiddleware` | `aquilia/i18n/middleware.py` | | Aquilia middleware that resolves locale and injects i18n into requests. | | `I18nConfig` | `aquilia/i18n/service.py` | `from_dict`, `to_dict` | Configuration for the i18n service. | Runtime Wiring Paths - `workspace.py` defines workspace-level structure with `Workspace`, `Module`, and `Integration` builders. - `modules/<name>/manifest.py` defines module internals with `AppManifest`. - `ConfigLoader.get(...)` resolves dotted configuration paths at runtime. - `AquiliaServer` consumes resolved config during middleware and subsystem setup. - Subsystems with optional providers only require optional dependencies when their backend/provider is configured. Verification Checklist 1. Run `aq validate` to verify manifests. 2. Run `aq inspect config` to inspect resolved configuration. 3. Run `aq doctor` for workspace and integration diagnostics. 4. For server-only wiring, start via `aq run` and check startup logs plus `GET /_health`. Related Pages - `api-reference.md` for exact class fields, methods, constants, and signatures. - `integration-guide.md` for the workspace/manifest wiring pattern. - `edge-cases-and-limitations.md` for fallback and compatibility behavior.


---

## Framework Docs: docs/i18n/cli-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-cli-reference`

<!-- Legacy mirror. Canonical page: ../modules/i18n/cli-reference.md --> I18N CLI Reference This page is derived from the mounted Click command tree. If a source file has CLI helper functions but they are not mounted under `aq`, this page states that explicitly. Relationship To The `aq` CLI The following mounted commands map to this subsystem. | Command | Syntax | Purpose | | --- | --- | --- | | `aq i18n init` | `aq i18n init [--locales VALUE] [--directory VALUE] [--format VALUE]` | Initialize i18n in the current workspace. | | `aq i18n check` | `aq i18n check` | Validate i18n configuration and catalog structure. | | `aq i18n inspect` | `aq i18n inspect` | Display current i18n configuration as JSON. | | `aq i18n extract` | `aq i18n extract [--source-dirs VALUE] [--output VALUE] [--no-merge]` | Extract translation keys from source files. | | `aq i18n coverage` | `aq i18n coverage` | Show translation coverage per locale. | | `aq i18n compile` | `aq i18n compile [--directory VALUE] [--output VALUE]` | Compile JSON locale files to SURP format. | Detailed Commands `aq i18n init` Initialize i18n in the current workspace. | Kind | Name | Flags | Required | Default | Help | | --- | --- | --- | --- | --- | --- | | Option | `locales` | `--locales, -l` | False | `en` | Comma-separated locale list (e.g. en,fr,de) | | Option | `directory` | `--directory, -d` | False | `locales` | Base directory for locale files | | Option | `format` | `--format, -f` | False | `json` | Translation file format | `aq i18n check` Validate i18n configuration and catalog structure. `aq i18n inspect` Display current i18n configuration as JSON. `aq i18n extract` Extract translation keys from source files. | Kind | Name | Flags | Required | Default | Help | | --- | --- | --- | --- | --- | --- | | Option | `source_dirs` | `--source-dirs, -s` | False | `modules,controllers` | Comma-separated source directories | | Option | `output` | `--output, -o` | False | `locales/en/messages.json` | Output file path | | Option | `no_merge` | `--no-merge` | False | `False` | Overwrite output instead of merging | `aq i18n coverage` Show translation coverage per locale. `aq i18n compile` Compile JSON locale files to SURP format. | Kind | Name | Flags | Required | Default | Help | | --- | --- | --- | --- | --- | --- | | Option | `directory` | `--directory` | False | `locales` | Source locales directory | | Option | `output` | `--output` | False | `` | Output directory for compiled catalogs | General Commands Useful For This Module | Command | Why it matters | | --- | --- | | `aq validate` | Validates workspace manifests and catches invalid component paths. | | `aq doctor` | Runs environment, workspace, manifest, registry, integration, and deployment diagnostics. | | `aq inspect config` | Shows resolved config after workspace/env merging. | | `aq inspect modules` | Lists discovered modules. | | `aq inspect routes` | Shows compiled routes when the module contributes controllers. | | `aq run` | Starts the dev server and executes startup wiring. | Error Behavior - Click handles missing required arguments and invalid options before command callbacks run. - Most operational commands require `workspace.py`; the root CLI guard allows help/version/init/doctor without it. - Commands that touch external providers, databases, or files can fail with subsystem-specific faults or provider errors.

### Code Examples
```python
aq i18n init [--locales VALUE] [--directory VALUE] [--format VALUE]

```

```python
aq i18n check

```

```python
aq i18n inspect

```



---

## Framework Docs: docs/i18n/api-reference.md
**URL**: `https://tubox.cloud/docs/framework/docs-i18n-api-reference`

<!-- Legacy mirror. Canonical page: ../modules/i18n/api-reference.md --> I18N API Reference This page is generated from the current Python source using the AST. It lists public classes, public methods, public module-level functions, constants, exports, and source files. Source Inventory | File | Lines | Classes | Functions | Purpose | | --- | ---: | ---: | ---: | --- | | `aquilia/i18n/__init__.py` | 182 | 0 | 0 | AquilaI18n — Industry-grade Internationalization & Localization for Aquilia. | | `aquilia/i18n/catalog.py` | 810 | 6 | 1 | Translation Catalogs — Storage and retrieval of translation strings. | | `aquilia/i18n/di_integration.py` | 183 | 0 | 2 | I18n DI Integration — Register i18n providers in Aquilia's DI container. | | `aquilia/i18n/faults.py` | 187 | 5 | 0 | I18n Faults — Typed fault signals for the i18n subsystem. | | `aquilia/i18n/formatter.py` | 627 | 1 | 9 | Message Formatter — ICU MessageFormat-inspired interpolation & locale formatting. | | `aquilia/i18n/lazy.py` | 289 | 2 | 4 | Lazy Strings — Deferred translation resolution. | | `aquilia/i18n/locale.py` | 352 | 1 | 5 | Locale — BCP 47 locale tag parsing, normalization, and negotiation. | | `aquilia/i18n/middleware.py` | 423 | 8 | 1 | I18n Middleware — Request-scoped locale resolution & injection. | | `aquilia/i18n/plural.py` | 515 | 1 | 2 | Plural Rules — CLDR-based plural category selection for 200+ languages. | | `aquilia/i18n/service.py` | 425 | 3 | 1 | I18n Service — Central orchestrator for all translation operations. | | `aquilia/i18n/template_integration.py` | 197 | 1 | 1 | I18n Template Integration — Jinja2 globals, filters, and extensions. | Public Exports `CLDR_PLURAL_RULES`, `CatalogLoadFault`, `ChainLocaleResolver`, `CookieLocaleResolver`, `SurpCatalog`, `FileCatalog`, `HeaderLocaleResolver`, `I18nConfig`, `I18nFault`, `I18nMiddleware`, `I18nService`, `I18nTemplateExtension`, `InvalidLocaleFault`, `LazyString`, `Locale`, `LocaleResolver`, `MemoryCatalog`, `MergedCatalog`, `MessageFormatter`, `MissingTranslationFault`, `NamespacedCatalog`, `PathLocaleResolver`, `PluralCategory`, `PluralRule`, `PluralRuleFault`, `QueryLocaleResolver`, `SessionLocaleResolver`, `TranslationCatalog`, `create_i18n_service`, `format_currency`, `format_date`, `format_datetime`, `format_decimal`, `format_message`, `format_number`, `format_ordinal`, `format_percent`, `format_time`, `get_plural_rule`, `has_surp`, `lazy_t`, `lazy_tn`, `match_locale`, `negotiate_locale`, `normalize_locale`, `parse_accept_language`, `parse_locale`, `register_i18n_providers`, `register_i18n_template_globals`, `select_plural` Public Class Summary | Class | Source | Bases | Summary | | --- | --- | --- | --- | | `TranslationCatalog` | `aquilia/i18n/catalog.py` | ABC | Abstract base for translation catalogs. | | `MemoryCatalog` | `aquilia/i18n/catalog.py` | TranslationCatalog | In-memory translation catalog backed by nested dicts. | | `FileCatalog` | `aquilia/i18n/catalog.py` | TranslationCatalog | File-based translation catalog loading from ``locales/`` directory. | | `SurpCatalog` | `aquilia/i18n/catalog.py` | TranslationCatalog | SURP artifact-backed translation catalog. | | `NamespacedCatalog` | `aquilia/i18n/catalog.py` | TranslationCatalog | Wraps a catalog with a fixed namespace prefix. | | `MergedCatalog` | `aquilia/i18n/catalog.py` | TranslationCatalog | Layered catalog that queries multiple catalogs with fallback. | | `I18nFault` | `aquilia/i18n/faults.py` | Fault | Base fault for all i18n-related errors. | | `MissingTranslationFault` | `aquilia/i18n/faults.py` | I18nFault | Raised when a translation key cannot be found in any catalog. | | `InvalidLocaleFault` | `aquilia/i18n/faults.py` | I18nFault | Raised when a locale tag cannot be parsed as valid BCP 47. | | `CatalogLoadFault` | `aquilia/i18n/faults.py` | I18nFault | Raised when a translation catalog file cannot be loaded. | | `PluralRuleFault` | `aquilia/i18n/faults.py` | I18nFault | Raised when plural form selection fails. | | `MessageFormatter` | `aquilia/i18n/formatter.py` | object | ICU MessageFormat-inspired string formatter. | | `LazyString` | `aquilia/i18n/lazy.py` | object | A string-like object that defers translation until stringification. | | `LazyPluralString` | `aquilia/i18n/lazy.py` | LazyString | Lazy string with plural support. | | `Locale` | `aquilia/i18n/locale.py` | object | Immutable BCP 47 locale tag. | | `LocaleResolver` | `aquilia/i18n/middleware.py` | ABC | Abstract locale resolver. | | `HeaderLocaleResolver` | `aquilia/i18n/middleware.py` | LocaleResolver | Resolve locale from the ``Accept-Language`` HTTP header. | | `CookieLocaleResolver` | `aquilia/i18n/middleware.py` | LocaleResolver | Resolve locale from a cookie. | | `QueryLocaleResolver` | `aquilia/i18n/middleware.py` | LocaleResolver | Resolve locale from a query parameter. | | `PathLocaleResolver` | `aquilia/i18n/middleware.py` | LocaleResolver | Resolve locale from the URL path prefix. | | `SessionLocaleResolver` | `aquilia/i18n/mi


---

## Framework Docs: releases/1.3.1/backends.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.1-backends`

Pluggable Authentication Backends In Aquilia v1.3.1, the authentication workflow is decomposed into single-responsibility **Backends**. A backend is a class that conforms to the `AuthBackend` protocol. It is responsible for accepting a credential dictionary and resolving it to an `Identity`. The `AuthBackend` Protocol The `AuthBackend` protocol is defined in `aquilia.auth.backends.base` using Python's structural subtyping (`typing.Protocol`): --- Built-in Backends Aquilia provides four native backends to cover standard flows: 1. `TokenBackend` Validates JWT Bearer tokens. It verifies signatures, checks `exp` and `nbf` claims (with clock-skew tolerance), and validates token revocation via `TokenManager`. * **Accepted Credentials**: `{"token": str}` * **Constructor**: 2. `SessionBackend` Restores identity from a cookie-backed session. It looks up the `identity_id` from the session data or from `session.principal`, and fetches the corresponding active identity. * **Accepted Credentials**: `{"session": Session}` * **Constructor**: 3. `PasswordBackend` Authenticates user login credentials. It checks for IP/username brute-force lockouts, resolves usernames or email addresses to an identity, compares password hashes, handles password re-hashing when algorithm parameters upgrade, and checks for multi-factor authentication (MFA) requirements. * **Accepted Credentials**: `{"username": str, "password": str}` * **Constructor**: 4. `ApiKeyBackend` Authenticates API requests via an opaque API key. It hashes the incoming key using `HMAC-SHA256` for lookup, checks expiration and revocation status, and verifies that the key carries the required scopes if requested. * **Accepted Credentials**: `{"api_key": str, "required_scopes": list[str] | None}` * **Constructor**: --- The Backend Resolver To simplify instantiation, the `resolve_backend` function maps string identifiers, class references, or dotted import paths to their instantiated backends: It maps: * Short names: `"token"` (TokenBackend), `"session"` (SessionBackend), `"password"` (PasswordBackend), `"api_key"` (ApiKeyBackend). * Class references: `TokenBackend`, `SessionBackend`, `PasswordBackend`, `ApiKeyBackend`. * Dotted paths: `"my_app.auth.backends.CustomBackend"`. Example Configuration in `workspace.py`

### Code Examples
```python
from typing import Any, Protocol, runtime_checkable
from aquilia.auth.core import Identity

@runtime_checkable
class AuthBackend(Protocol):
    def accepts(self, credentials: dict[str, Any]) -> bool:
        """Return True if the backend supports the provided credentials."""
        ...

    async def authenticate(self, credentials: dict[str, Any]) -> Identity | None:
        """Verify credentials and resolve them to an Identity.
        
        May raise specific auth faults (e.g., AUTH_TOKEN_EXPIRED, AUTH_INVALID_CREDENTIALS).
        """
        ...

```

```python
def __init__(self, token_manager: TokenManager, identity_store: IdentityStore)
  
```

```python
def __init__(self, identity_store: IdentityStore)
  
```



---

## Framework Docs: releases/1.3.1/migration.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.1-migration`

Migration Guide: v1.3.0 to v1.3.1 Aquilia v1.3.1 consolidates and standardizes authentication and authorization. Follow this guide to upgrade your project. --- 1. Upgrading Configuration The string-based `strategies` setting has been removed. You must now configure the list of identity-resolution backends using the `backends` parameter. Additionally, the rate-limiting and MFA settings have been promoted to direct configuration parameters on `AquilaConfig.Auth`. Legacy Configuration (v1.3.0) Refactored Configuration (v1.3.1) --- 2. Replaced & Removed Decorators The legacy decorators `AdminGuard` and `VerifiedEmailGuard` have been removed. * **`AdminGuard`**: Replace with `@roles_required("admin")`. * **`VerifiedEmailGuard`**: Handle verification checks in your identity resolution backend (such as deactivating unverified users) or write a simple custom guard. Before: After: --- 3. Upgrading Flow Pipeline Guards All legacy guard adapters (historically located in `flow_guards.py`) have been removed. Use the new first-class guards directly. | Legacy Guard Class (v1.3.0) | Refactored Guard Class (v1.3.1) | |---|---| | `RequireAuthGuard` | `AuthGuard` | | `RequireRolesGuard` | `RoleGuard` | | `RequireScopesGuard` | `ScopeGuard` | | `RequirePolicyGuard` | `PolicyGuard` | Pipeline Registration Example Before: After: --- 4. Upgrading Session Guards The legacy `SessionGuard` class and `@requires` decorator in `aquilia.sessions.decorators` have been removed. Switch to the unified `PermissionEngine` and the unified `@requires` decorator. Before: After: --- 5. Removing the Fluent `AuthConfig` Builder If you set up custom authentication containers in testing or bootstrapping scripts using the `AuthConfig` builder, you must remove it. Configure integrations directly using dictionary payloads or the `AquilaConfig.Auth` classes. Before: After: --- 6. Deprecated APIs & Relocations * **`AuthManager.logout()`**: Deprecated in favor of `AuthManager.sign_out()`. Calling `logout()` now raises a `DeprecationWarning` but will invoke `sign_out()` internally for backward compatibility. * **`OptionalAuthMiddleware`**: Deprecated in favor of `AquilAuthMiddleware(require_auth=False)` or the new `AuthMiddleware` class. * **`RateLimiter` relocation**: The `RateLimiter` class has been moved from the `manager` module to `aquilia.auth.manager_types` to prevent circular imports. Update imports if you reference it directly. * **`ServiceScope` Enum class**: Deprecated in favor of plain string literals (e.g., `"singleton"`, `"app"`, `"request"`, `"transient"`, `"pooled"`, `"ephemeral"`) paired with `typing.Literal` type hints (`ServiceScopeLiteral`). Using `ServiceScope.SINGLETON` or other members will now emit a `DeprecationWarning`.

### Code Examples
```python
class auth(AquilaConfig.Auth):
    secret_key = Secret(env="AQ_SECRET_KEY", default="change-me")
    strategies = ["token", "session"]

```

```python
class auth(AquilaConfig.Auth):
    secret_key = Secret(env="AQ_SECRET_KEY", default="change-me")
    backends = [
        "aquilia.auth.backends.TokenBackend",
        "aquilia.auth.backends.SessionBackend",
    ]
    # Store type: "memory" or "redis"
    store_type = "memory"
    
    # Rate Limiting configuration parameters
    rate_limit_max_attempts = 5
    rate_limit_window_seconds = 900
    rate_limit_lockout_seconds = 3600
    
    # MFA settings
    mfa_enabled = False
    mfa_required = False
    
    # Clock skew tolerance (in seconds) for JWT validations
    clock_skew_seconds = 5
    
    # Audit trail activation
    audit_enabled = True

```

```python
from aquilia.auth import AdminGuard

@AdminGuard
async def delete_item(ctx):
    ...

```



---

## Framework Docs: releases/1.3.1/README.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.1-README`

Aquilia v1.3.1 Release Notes — "Backend Refactoring" Aquilia v1.3.1 introduces a major rewrite of the authentication (`aquilia.auth`) and authorization subsystems. It moves away from rigid string-based strategies and hardcoded guard adapters in favor of a pluggable, class-based backend architecture, a unified permission engine, hardened session serialization, and token clock-skew tolerance. Table of Contents 1. [Pluggable Authentication Backends](backends.md) * The new `AuthBackend` protocol. * Built-in backends: `TokenBackend`, `SessionBackend`, `PasswordBackend`, `ApiKeyBackend`. * The `resolve_backend` helper and loading configuration. 2. [Unified Permission & Authorization Engine](guards.md#permissionengine) * Role DAG (Directed Acyclic Graph) inheritance. * Policy callables and scope checks. * Pluggable Flow Guards: `AuthGuard`, `RoleGuard`, `ScopeGuard`, `PolicyGuard`. * Context-First Decorators: `@authenticated`, `@roles_required`, `@scopes_required`, `@optional_auth`. 3. [Session Security Hardening](sessions.md) * Elimination of stale permission state in session cookies. * The lightweight `AuthPrincipal` serialization format. * Dynamic resolution of roles and scopes on every request. 4. [Migration Guide](migration.md) * Upgrading configuration settings from `strategies` to `backends`. * Replaced classes, decorators, and middleware. --- Key Refactoring Goals 1. **Pluggability**: Unify all authentication strategies (Bearer JWTs, Session cookies, Username/Password, API keys) under a single, reusable backend protocol. 2. **Dynamic Privileges**: Resolve permissions, roles, and scopes fresh from the database or cache on every request, preventing privilege escalation through stale session states. 3. **API Simplification**: Consolidate five parallel authorization subsystems (RBAC, ABAC, Clearance, Policy DSL, and custom adapters) into a single, cohesive `PermissionEngine`. 4. **Resiliency**: Handle clock drift in distributed clusters by introducing native clock-skew tolerance. 5. **DI Scope Performance**: Deprecate the class/object-based `ServiceScope` Enum in favor of high-performance raw string literals backed by `typing.Literal` to eliminate import-time namespace scanning and runtime attribute lookup overhead.


---

## Framework Docs: releases/1.3.1/guards.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.1-guards`

Unified Authorization, Middleware & Decorators Aquilia v1.3.1 unifies identity resolution and request-scoped checks into a single middleware and permission engine. --- 1. Unified `PermissionEngine` The `PermissionEngine` (defined in `aquilia.auth.permissions`) is the central engine for evaluating roles, scopes, and policies. It replaces five separate historical systems and runs check assertions that raise appropriate exceptions on denial. Core API Methods * `define_role(role: str, *, permissions: list[str] | None = None, inherits: list[str] | None = None) -> None`: Declare a role and its transitively implied parents. * `role_implies(role: str, target: str) -> bool`: Query the role DAG structure. * `register_policy(key: str, policy: PolicyCallable) -> None`: Define a rule matching the signature `(identity, resource) -> bool`. * `check_role(identity: Identity, role: str) -> None`: Asserts role ownership; raises `AUTHZ_INSUFFICIENT_ROLE` on failure. * `check_scope(identity: Identity, scope: str) -> None`: Asserts scope ownership; raises `AUTHZ_INSUFFICIENT_SCOPE` on failure. * `check_policy(key: str, identity: Identity, resource: Any = None) -> None`: Asserts policy assertion passes; raises `AUTHZ_POLICY_DENIED` on failure. * `has_role(identity: Identity, role: str) -> bool`: Returns a boolean indicating role membership. * `has_scope(identity: Identity, scope: str) -> bool`: Returns a boolean indicating scope membership. * `evaluate_policy(key: str, identity: Identity, resource: Any = None) -> bool`: Returns a boolean indicating policy result. --- 2. Pluggable Flow Guards Guards (defined in `aquilia.auth.guards`) evaluate context and raise exceptions on denial. They can be placed directly in request pipelines or used as raw classes (for zero-configuration defaults). `AuthGuard` Verifies authentication status. * **Optional Mode**: When `optional=True`, anonymous users are allowed. * **Proactive Auth**: If the identity is not yet resolved, `AuthGuard` attempts to proactively extract and authenticate a Bearer token using DI container-resolved `AuthManager`. * **Signature**: `AuthGuard(auth_manager=None, optional=False)` `RoleGuard` Ensures the identity holds required roles. * **Resolution**: Uses `PermissionEngine` if found in the DI container; otherwise, falls back to direct membership testing of `identity.get_attribute("roles", [])`. * **Signature**: `RoleGuard(*roles, engine=None, require_all=True)` `ScopeGuard` Ensures the identity holds required scopes. * **Wildcards**: Supports the wildcard `"*"` scope. * **Signature**: `ScopeGuard(*scopes, require_all=True)` `PolicyGuard` Evaluates a policy registered in the permission engine. * **Signature**: `PolicyGuard(key, engine, resource=None)` --- 3. Context-First Decorators Decorators (defined in `aquilia.auth.decorators`) wrap handlers to execute guard checks and **inject parameters** into the handler's signature (e.g., `identity`, `user`, `session`, `principal`). `@authenticated` Requires an authenticated identity. * **Browser Redirection**: If a request is anonymous, has `redirect_if_html=True` or `login_url` configured, and accepts HTML, it performs a `303 Redirect` to the login page with a `next` query parameter. * **Signature**: `@roles_required` / `@scopes_required` Evaluates role or scope conditions before executing the controller action. `@optional_auth` Evaluates the proactive `AuthGuard(optional=True)` check. It injects the user if found but does not block anonymous traffic. `@requires` Composes multiple guards (both classes and instances) sequentially: --- 4. Unified `AuthMiddleware` The new unified `AuthMiddleware` (defined in `aquilia.auth.middleware`) coordinates credential resolution from backends on every incoming request. * **Signatures & Parameters**: * **Execution Flow**: 1. **Phase 1: Session Resolution**: If `session_engine` is provided, resolves the session and binds it to `ctx.session` and `request.state["session"]`. 2. **Phase 2: Credentials Extraction**: Extracts Bearer token, ApiKey, or Session from the request. 3. **Phase 3: Backend Authentication**: Loops through pluggable `backends` (defaults to `TokenBackend` and `SessionBackend`). The first backend that accepts the credentials and returns an `Identity` completes the phase. 4. **Phase 4: Requirement Enforcement**: If `require_auth=True` and no identity is resolved, returns a `401 Unauthorized` response immediately. 5. **Phase 5: Propagation**: Propagates the resolved identity to `request.state["identity"]`, `request.state["authenticated"]`, and `ctx.identity`. 6. **Phase 6: Downstream Execution**: Calls the next handler in the ASGI middleware chain. 7. **Phase 7: Session Commitment**: Commits session modifications back to the storage adapter.

### Code Examples
```python
def authenticated(
      func=None,
      *,
      login_url: str | None = None,
      redirect_if_html: bool = False,
      include_next: bool = True,
      next_param: str = "next",
      redirect_status: int = 303,
  )
  
```

```python
@roles_required("admin", "editor", require_all=False)
async def delete_post(self, ctx: RequestCtx) -> Response:
    ...

```

```python
@requires(AuthGuard, RoleGuard("admin"))
async def admin_only_action(self, ctx: RequestCtx) -> Response:
    ...

```



---

## Framework Docs: releases/1.3.1/sessions.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.1-sessions`

Session Security, AuthManager & RateLimiting Aquilia v1.3.1 introduces substantial security improvements to cookie-based and session-based authentication to prevent privilege escalation, alongside a refined `AuthManager` API and a standalone `RateLimiter` utility. --- 1. Session Serialization Hardening In previous versions of Aquilia, the full set of user roles, scopes, and attributes was serialized and stored directly inside the session store database (or client-side cookie): This optimization meant that if an administrator modified a user's permissions, suspended their account, or deleted them, the changes **would not take effect** for requests authenticated via session cookies until their session expired. In Aquilia v1.3.1, session serialization has been hardened. The `bind_identity` function only writes core identifiers: Notice that **roles, scopes, and user attributes are no longer written to the session store**. Active Identity Resolution * The `SessionBackend` captures the active session credentials. * It extracts the `identity_id` (either from `session.principal` or from `session.data["identity_id"]`). * It fetches a fresh `Identity` object directly from the `IdentityStore` on **every single request**. * Authorization guards evaluate roles and scopes against this fresh database/cache state. --- 2. Shared Manager Types: `RateLimiter` To protect brute-force paths (such as username/password login), Aquilia v1.3.1 introduces a standalone `RateLimiter` class in `aquilia.auth.manager_types` (and re-exported in `aquilia.auth.manager` for backward compatibility). * **Constructor & Parameters**: Tracks failed authentication attempts per key (typically a username or IP address) within a sliding time window. * **Core API Methods**: * `record_attempt(key: str) -> None`: Records a failed attempt. If attempts exceed `max_attempts` within the window, locks out the key. * `is_locked_out(key: str) -> bool`: Checks if the key is currently locked out. * `get_remaining_attempts(key: str) -> int`: Returns attempts left before lockout. * `reset(key: str) -> None`: Clears attempt history for the key on successful authentication. --- 3. `AuthManager` Refactored APIs The `AuthManager` class (defined in `aquilia.auth.manager`) is the central coordinator for authentication operations. The following APIs were updated: Token Revocation The token revocation API now supports access tokens by extracting the unique JWT identifier (`jti`) and blacklisting it: * `async def revoke_token(self, token: str, token_type: str = "refresh") -> None`: * If `token_type == "refresh"`, revokes the refresh token directly. * If `token_type == "access"`, validates the access token, extracts the `jti` claim, and revokes it so subsequent validations reject it. Deprecated `logout()` * **Signature**: `async def logout(self, identity_id=None, session_id=None, access_token=None, refresh_token=None) -> None` * **Status**: **Deprecated** in favor of `sign_out()`. Raises a `DeprecationWarning` when called. --- 4. `SessionAuthBridge` The `SessionAuthBridge` coordinates actions between `AuthManager` and `SessionEngine`: * `create_auth_session(identity, request, token_claims=None)`: Resolves and binds authentication credentials to a new session. * `rotate_on_privilege_escalation(session, response)`: Rotates the session ID (session fixation protection) after an escalating event (such as completing an MFA challenge). * `logout(session, response)`: Destroys the current session. * `logout_all_devices(identity_id)`: Revokes and purges all active session identifiers linked to a given identity ID across the session store.

### Code Examples
```python
# Old, insecure v1.3.0 implementation:
session["roles"] = identity.get_attribute("roles", [])
session["scopes"] = identity.get_attribute("scopes", [])
session["status"] = identity.status.value

```

```python
# Hardened v1.3.1 implementation:
session.mark_authenticated(AuthPrincipal.from_identity(identity))
session["identity_id"] = identity.id
if identity.tenant_id is not None:
    session["tenant_id"] = identity.tenant_id

```

```python
def __init__(
      self,
      max_attempts: int = 5,
      window_seconds: int = 900,
      lockout_duration: int = 3600,
  )
  
```



---

## Framework Docs: releases/1.3.3/recursive_cte.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-recursive_cte`

Recursive CTEs — Aquilia v1.3.3 Recursive CTEs use `WITH RECURSIVE` to traverse hierarchical or graph structures in a single SQL query. They consist of: 1. **Anchor term** — the base case (e.g., root nodes) 2. **Recursive term** — references the CTE itself to walk to the next level 3. **UNION / UNION ALL** — combines both terms --- API `Q.recursive_cte(name, anchor, recursive, *, union_all=True) → Q` Builds and registers a recursive CTE, returning a queryset that selects from the named CTE table. **Arguments** | Argument | Type | Description | |---|---|---| | `name` | `str` | SQL identifier for the CTE (validated against `_SAFE_FIELD_RE`) | | `anchor` | `Callable[[Q], Q]` | Receives a fresh queryset; return the base case | | `recursive` | `Callable[[CTEReference], Q]` | Receives a `CTEReference`; return the recursive term | | `union_all` | `bool` | `True` (default) = `UNION ALL`; `False` = `UNION` (deduplication) | **Returns** a `Q` queryset with `_table = name` and the `RecursiveCTE` registered. Call terminal methods (`.all()`, `.filter().all()`, etc.) on the returned queryset. --- CTEReference Inside the `recursive` lambda, the parameter is a `CTEReference` that represents the partially-built CTE from the previous iteration. `cte.col("field")` returns a `CTECol` expression that renders as `"cte_name"."field"`, safe for use in any filter or annotation. --- Practical Examples Folder / category tree Employee org chart (subtree from manager) Comment thread (nested replies) Dependency graph — transitive closure --- UNION vs UNION ALL | Mode | Use when | |---|---| | `union_all=True` (default) | Tree structures with no cycles (folder trees, org charts) — faster, avoids dedup overhead | | `union_all=False` | Graph structures where cycles are possible (dependency graphs, network routes) — deduplication prevents infinite loops | > **Note:** `UNION` deduplication prevents infinite traversal loops in > directed graphs, but only if duplicates are meaningful. For deep trees, > prefer `UNION ALL` and add a depth limit via a counter column if needed. --- Adding Depth / Path Tracking For depth tracking, use `annotate()` on the anchor and a computed field: --- RecursiveCTE Object `Q.recursive_cte(...)` internally constructs a `RecursiveCTE` instance: --- Backend Compatibility | Feature | SQLite | PostgreSQL | MySQL | MariaDB | |---|---|---|---|---| | `WITH RECURSIVE` | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `UNION ALL` in recursive | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `UNION` dedup in recursive | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 |

### Code Examples
```python
sql
WITH RECURSIVE "folder_tree" AS (
    SELECT * FROM "folders" WHERE ("parent_id" IS NULL)
    UNION ALL
    SELECT f.* FROM "folders" f
    INNER JOIN "folder_tree" ft ON f."parent_id" = ft."id"
)
SELECT * FROM "folder_tree"

```

```python
tree = await Folder.objects.recursive_cte(
    name="folder_tree",
    anchor=lambda q: q.filter(parent_id__isnull=True),
    recursive=lambda cte: Folder.objects.filter(
        parent_id=cte.col("id")
    ),
).all()

```

```python
lambda cte: Folder.objects.filter(parent_id=cte.col("id"))
#                                             ^^^^^^^^^^^
#                                    CTECol("folder_tree", "id")
#                                    renders: "folder_tree"."id"

```



---

## Framework Docs: releases/1.3.3/backends.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-backends`

Backend Compatibility — Aquilia v1.3.3 Window Functions | Function | SQLite | PostgreSQL | MySQL | MariaDB | |---|---|---|---|---| | `RANK()` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `DENSE_RANK()` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `ROW_NUMBER()` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `NTILE(n)` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `LAG(expr, n, default)` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `LEAD(expr, n, default)` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `FIRST_VALUE(expr)` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `LAST_VALUE(expr)` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `NTH_VALUE(expr, n)` | ≥ 3.25 | ≥ 11 | ≥ 8.0.2 | ≥ 10.6 | | Aggregate windows (SUM/AVG etc.) | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `ROWS BETWEEN` frame | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `RANGE BETWEEN` frame | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `GROUPS BETWEEN` frame | ≥ 3.28 | ≥ 11 | ✗ | ✗ | > **SQLite note**: Check your SQLite version with `SELECT sqlite_version()`. > macOS ships SQLite ≥ 3.39 as of macOS 12. The system SQLite on older macOS > may be < 3.25 — in that case, install a modern SQLite via Homebrew. CTEs | Feature | SQLite | PostgreSQL | MySQL | MariaDB | |---|---|---|---|---| | Non-recursive CTE | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | Multiple CTEs in one query | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | Recursive CTE | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `UNION ALL` in recursive | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | `UNION` dedup in recursive | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | ≥ 10.2 | | CTE in UPDATE/DELETE | ✗ | ≥ 9.1 | ✗ | ≥ 10.6 | | Materialisation hints | ✗ | ≥ 12 | ✗ | ✗ | > **MySQL note**: MySQL 8.0 added CTE support. MySQL 5.7 and older do not > support CTEs. If you target MySQL 5.7, avoid `with_cte()` and > `recursive_cte()`. ORM Bug Fixes | Fix | Affected versions | Fixed in | |---|---|---| | `UUIDField(auto=True)` NULL insert | All prior | 1.3.3 | | Transaction depth `WeakValueDictionary` leak | All prior | 1.3.3 | | `Q.where()`/`Q.having()` inconsistent/incomplete raw-SQL blocklist | All prior | 1.3.3 | | `EncryptedMixin.to_db()` `TypeError` on `dialect=` keyword | All prior (never exercised through `Model.save()` before) | 1.3.3 | See [Security & Concurrency Hardening](security_hardening.md) for full root-cause detail. Enterprise Field Types | Field | SQLite | PostgreSQL | MySQL/MariaDB | Oracle | New dependency | |---|---|---|---|---|---| | `MoneyField` | ✓ (`DECIMAL`) | ✓ (`DECIMAL`) | ✓ (`DECIMAL`) | ✓ (`NUMBER`) | None | | `EncryptedField` | ✓ (`TEXT`) | ✓ (`TEXT`) | ✓ (`TEXT`) | ✓ (`CLOB`) | None (`cryptography` optional) | | `PointField` / `GeometryField` | ✓ (`TEXT`) | ✓ (`JSONB`) | ✓ (`TEXT`) | ✓ (`CLOB`) | None | | `GenericForeignKey` | ✓ | ✓ | ✓ | ✓ | None (owns no column) | See [Enterprise Field Types](enterprise_fields.md) for usage and examples. Checking Your SQLite Version Minimum supported: SQLite **3.8.3** for CTEs, **3.25** for window functions. Checking Your PostgreSQL Version Capability Detection at Runtime Aquilia does not currently expose a runtime capability matrix API. If you need to guard production code against unsupported backends, check the dialect: A first-class `backend.supports_window_functions` / `backend.supports_cte` capability flag API is planned for a future release.

### Code Examples
```python
import sqlite3
print(sqlite3.sqlite_version)  # e.g., "3.45.1"

```

```python
sql
SELECT version();

```

```python
db = get_database()
dialect = db.driver  # "sqlite" | "postgresql" | "mysql"

if dialect == "mysql":
    # MySQL < 8.0 does not support CTEs
    pass  # add your own version check here

```



---

## Framework Docs: releases/1.3.3/cte.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-cte`

CTEs — Common Table Expressions — Aquilia v1.3.3 CTEs let you name a subquery and reference it one or more times in the main query. They improve readability, enable query composition, and on some databases allow the optimiser to materialise intermediate results. --- API `Q.cte(name) → CTE` Creates a named CTE from the queryset. Does **not** execute anything. `Q.with_cte(*ctes) → Q` Registers one or more CTEs into the query's `WITH` clause. Chainable. Generated SQL: Parameters: `[True, "admin"]` — CTE params always come first. --- CTE Objects `CTE(name, queryset)` Returned by `Q.cte(name)`. Carries the name and the compiled inner queryset. `CTECol(cte_name, column)` An `Expression` that renders as `"cte_name"."column"`. Used to reference CTE output columns inside other queries or annotations. `CTEReference` Used inside `recursive_cte()` lambdas. See [Recursive CTE docs](recursive_cte.md). --- Multiple CTEs Chain `.with_cte()` calls or pass multiple CTEs in one call: Generated SQL: --- Practical Examples Rank-filtered results using CTE Analytics pipeline with multiple CTEs --- CTE Parameter Ordering Bind parameters from CTEs are always prepended before annotation parameters and WHERE parameters in the final parameter list. This ensures correct positional binding regardless of where CTEs appear visually in the SQL. --- Backend Compatibility | Feature | SQLite | PostgreSQL | MySQL | |---|---|---|---| | Non-recursive CTEs | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 | | Multiple CTEs | ≥ 3.8.3 | ≥ 8.4 | ≥ 8.0 |

### Code Examples
```python
sql
WITH active_users AS (
    SELECT * FROM "users" WHERE ("is_active" = ?)
)
SELECT * FROM "users" WHERE ...

```

```python
active_cte = User.objects.filter(is_active=True).cte("active_users")

```

```python
result = await (
    User.objects
    .with_cte(active_cte)
    .filter(role="admin")
    .all()
)

```



---

## Framework Docs: releases/1.3.3/bugfixes.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-bugfixes`

Bug Fixes — Aquilia v1.3.3 Two genuine bugs in the ORM layer were discovered and fixed during a production-grade audit of `aquilia/models`. Both were confirmed from source code, reproduced in tests, and fixed with minimal, surgical changes. --- Fix 1 — `UUIDField(auto=True)` NULL Primary Key Insert Symptom Rows were inserted with `id = NULL` despite `auto=True` being set. Root Cause `UUIDField.__init__` builds a `kwargs` dict that always pre-populates `kwargs["default"] = default` (where `default = UNSET` when the caller didn't pass one): `dict.setdefault()` only acts when the key is **absent**. Since `"default"` was always pre-populated, the `uuid.uuid4` callable was never stored. `Field.has_default()` returned `False`, `get_default()` returned `None`, and the `INSERT` wrote `NULL` into the primary key column. Fix Replace the `setdefault` call with an explicit sentinel check: **File:** `aquilia/models/fields_module.py` Regression Tests — `tests/test_uuid_pk_auto.py` (34 tests) | Group | Coverage | |---|---| | `TestUUIDFieldInit` | `auto=True` sets callable default, explicit default honored, `auto=False` no default | | `TestUUIDFieldValidation` | UUID object, string, invalid string, None (nullable), empty string, wrong type | | `TestUUIDFieldSerialisation` | `to_python` / `to_db` round-trip for all backends | | `TestUUIDFieldSQLType` | `VARCHAR(36)` for SQLite/MySQL/Oracle, `UUID` for PostgreSQL | | `TestUUIDFieldDeconstruct` | `deconstruct()` includes field type | | `TestUUIDPkCreate` | `create()` sets UUID, two creates have distinct UUIDs, fetch by PK | | `TestUUIDPkRoundtrip` | `from_row()` deserialises, `filter(pk=uuid)` works | | `TestUUIDForeignKey` | FK child referencing UUID PK, multiple children same parent | --- Fix 2 — Transaction Nesting Depth Tracker Symptom Under concurrent workloads or after task recycling by asyncio, the transaction nesting depth could be: - **Stale from a previous task**: new task inherits `depth > 0`, so `Atomic.__aenter__` creates a `SAVEPOINT` instead of issuing `BEGIN`. No real transaction is ever opened. Rollbacks silently do nothing. - **Never cleaned up**: `_task_depths` accumulated integer keys from dead tasks, causing unbounded memory growth under high request concurrency. Root Cause The original implementation: Three bugs in one: 1. **Memory leak**: `WeakValueDictionary` holds *values* weakly — the integer `id(task)` keys are strong references that are never freed. One entry per task, forever. 2. **`id()` reuse contamination**: CPython recycles memory addresses. A new asyncio task may receive the same `id()` as a previously-GC'd task. If the stale `_DepthHolder` for that address still exists, the new task finds it and inherits the wrong depth. Depending on the stale value: - `depth > 0` on first enter → savepoint instead of `BEGIN` - `depth > 0` left over after exit → every subsequent enter is treated as nested, no top-level transactions ever open again 3. **Architecture inconsistency**: Every other Aquilia subsystem (controller, auth, DI, DB engine, inspector, i18n) uses `ContextVar` for task-local state. `WeakValueDictionary + id(task)` was the single outlier. Fix Replace the entire `_task_depths` / `_DepthHolder` / `_get_depth_holder` infrastructure with a single `ContextVar[int]`: In `Atomic.__aenter__`: In `Atomic.__aexit__`: `reset(token)` (not `set(depth - 1)`) ensures that if `__aenter__` raises before the token is stored, `__aexit__` is a safe no-op — no underflow. **File:** `aquilia/models/transactions.py` Why ContextVar Is Correct | Property | Old: WeakValueDict + id(task) | New: ContextVar[int] | |---|---|---| | Memory leak | Yes (integer keys never freed) | No (freed with task context) | | `id()` reuse contamination | Yes | No (each task gets own copy) | | Concurrency-safe | Unreliable | Yes (`set()` is local to current context) | | Child task isolation | None | Yes (child inherits at-copy-time value, mutations independent) | | Consistent with codebase | No | Yes | Regression Tests — `tests/test_txn_depth_contextvar.py` (19 tests) | Group | Coverage | |---|---| | `TestContextVarUsed` | `_txn_depth` is a `ContextVar`, default is 0, no `WeakValueDictionary` exported | | `TestDepthTracking` | 0 before enter, 1 inside outermost, 2 inside nested, restored after rollback, restored after nested rollback | | `TestConcurrencyIsolation` | Two `gather()` tasks see independent depths, sibling tasks start at 0, `id()` reuse doesn't contaminate | | `TestStress` | 50 concurrent tasks with nested atomics, no depth corruption | | `TestAtomicBehaviourAfterFix` | Commit/rollback still work, savepoint still works, durable rejected when nested, decorator form, on-commit/rollback hooks | --- Fix 3 — `Controller.render()` / `TemplateEngine` Resolution Failure (Issue #59) Symptom Calling `return await self.render("index.html")` inside a controller handler raised: Root Cause Analysis Audit of the template resolution lifecycle revealed five interlocking root causes: 1. **Async

### Code Examples
```python
class MyModel(Model):
    id = UUIDField(primary_key=True, auto=True)

instance = await MyModel.create(name="test")
print(instance.id)  # None  ← bug

```

```python
# Before fix — BROKEN
kwargs = {
    ...
    "default": default,   # always present, even when default=UNSET
    ...
}
if auto:
    kwargs.setdefault("default", uuid.uuid4)  # no-op: key already exists

```

```python
# After fix — CORRECT
if auto and default is UNSET:
    kwargs["default"] = uuid.uuid4

```



---

## Framework Docs: releases/1.3.3/migration.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-migration`

Migration Guide — Aquilia v1.3.3 v1.3.3 is a **backwards-compatible** release. No existing APIs are removed or changed. The two bug fixes affect only broken behaviour that no correct application could have been relying on. The new window/CTE features are purely additive. --- Breaking Changes **None**, with one caveat worth a second look: the widened `Q.where()`/ `Q.having()` raw-SQL blocklist (see [Security & Concurrency Hardening](security_hardening.md)) now also rejects `DELETE`, `INSERT`, `UPDATE`, `MERGE`, `--`, `/* */`, and bare `;` inside a raw clause string. If any of your code passes a raw `.where()`/`.having()` clause containing one of these as literal text (not just as a bind parameter value — bind parameters are unaffected), it will now raise `SecurityFault` where it previously didn't. This is vanishingly unlikely in a correct application (these keywords have no legitimate reason to appear in a `WHERE`/`HAVING` clause fragment), but worth a `pytest tests/ -k "where or having"`-style sanity pass if you have unusual raw-SQL usage. Everything else in this release is additive or fixes behaviour no correct application could have relied on. --- UUIDField(auto=True) Fix If you were working around the NULL-primary-key bug by supplying your own UUID in `create()`: This still works after the fix — explicitly-supplied UUIDs are honoured. You can safely remove the workaround if desired: --- Transaction Depth Fix No API changes. The `atomic()` context manager / decorator interface is unchanged. The fix is entirely internal to depth tracking. If your code explicitly accesses the internal `_txn_depth` ContextVar (unlikely, as it was not part of the public API), update to: --- New Imports All new symbols are exported from `aquilia.models`: They are also importable from the sub-modules directly: See [Enterprise Field Types](enterprise_fields.md) for full usage of each. --- New Q Methods | Method | Signature | Purpose | |---|---|---| | `Q.cte()` | `(name: str) → CTE` | Create named CTE from queryset | | `Q.with_cte()` | `(*ctes) → Q` | Register CTEs; returns new Q | | `Q.recursive_cte()` | `(name, anchor, recursive, *, union_all=True) → Q` | Build recursive CTE | All are chainable and return new `Q` instances (immutable clone pattern). No existing chain methods are affected. --- Dependency Requirements No new runtime dependencies. Window functions and CTEs are pure SQL features generated by the existing expression system. The implementation adds two new modules (`window.py`, `cte.py`) to `aquilia/models/` and extends `query.py` with three chain methods and two `__slots__` entries (`_ctes`, `_has_recursive_cte`). Python version requirement: **unchanged** (≥ 3.10).

### Code Examples
```python
# Old workaround (before fix)
import uuid
instance = await MyModel.create(id=uuid.uuid4(), name="test")

```

```python
# After fix — auto=True generates UUID automatically
instance = await MyModel.create(name="test")
assert instance.id is not None  # ✓ always True now

```

```python
# Before (broken — do not use)
from aquilia.models.transactions import _task_depths

# After
from aquilia.models.transactions import _txn_depth  # ContextVar[int]
current_depth = _txn_depth.get()  # 0 if outside any transaction

```



---

## Framework Docs: releases/1.3.3/security_hardening.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-security_hardening`

Security & Concurrency Hardening — Aquilia v1.3.3 Two ORM hardening fixes came out of a senior-engineer security assessment of the ORM layer, in the same audit spirit as the [bug fixes](bugfixes.md) also shipped in this release. Neither is a new vulnerability report — both close gaps between documented behavior and what the code actually enforced. --- Fix 1 — Raw-SQL Keyword Blocklist Was Inconsistent and Incomplete Symptom `Q.where()` and `Q.having()` are documented as low-level, developer-authored raw-clause APIs — parameter binding (`?` placeholders) is the actual injection defense, and both methods carry a secondary keyword-blocklist guardrail on top. But the two guardrails disagreed with each other and both had real gaps: `.where()` only checked for `DROP`, `ALTER`, `TRUNCATE`, `EXEC`, `EXECUTE` — via a trailing-space substring match, not even a proper identifier check. `.having()` had a separate, wider set (`DROP`, `ALTER`, `TRUNCATE`, `EXEC`, `EXECUTE`, `--`, `;`) but still missed `DELETE`/`INSERT`/`UPDATE`/`MERGE`, and its substring match could false-positive on legitimate identifiers. Root Cause Two independent, hand-maintained keyword sets, both under-scoped and neither using word-boundary matching: The trailing-space substring match in `.where()` also meant a column or identifier containing the keyword as a prefix (e.g. a hypothetical `"AIRDROP "` token) could match by accident — the check was neither correct nor complete. Fix One shared, word-boundary regex guard, used by both methods: `Q.where()` calls it unconditionally (unchanged, stricter behavior); `Q.having()` calls it only when no bind params were supplied (unchanged semantics — only the keyword set was widened). Word-boundary matching (`\b...\b`) means `updated_at`, `deleted_flag`, and similar identifiers are no longer false positives. > **Reminder:** this guard is a secondary net, not the injection defense. > Always bind user-supplied values through `?` placeholders — never > string-interpolate them into a raw clause, blocklist or not. **File:** `aquilia/models/query.py` Regression Tests — `tests/test_orm_security.py::TestWhereHavingClauseGuard` | Test | Coverage | |---|---| | `test_where_rejects_dml_and_ddl_keywords` | `DELETE`/`INSERT`/`UPDATE`/`MERGE`/`DROP` all rejected | | `test_where_rejects_comment_markers` | `--`, `/*`, `*/` all rejected | | `test_where_accepts_identifier_substrings` | `updated_at` passes — no false positive on `UPDATE` | | `test_having_rejects_dml_keywords_without_params` | Same DML set rejected on `.having()` | | `test_having_with_params_bypasses_keyword_scan` | Existing semantics preserved: keyword scan only runs when no bind params given | --- Fix 2 — `get_or_create()` / `update_or_create()` Silently Non-Atomic Symptom Both methods were already documented as "not atomic" in their docstrings, but nothing surfaced that fact at runtime. Under concurrent access, two callers could both miss the initial `SELECT` and both attempt an `INSERT`, risking a duplicate row or a unique-constraint violation — a classic time-of-check-to-time-of-use (TOCTOU) race, invisible until it happened in production. Root Cause `get_or_create()`/`update_or_create()` are, and always were, a plain SELECT-then-INSERT/UPDATE: `find_or_create()` (already shipped, using `INSERT ... ON CONFLICT`) is the race-free alternative — but a developer reaching for the more familiar `get_or_create()` name had no runtime indication that they should reach for the other one instead. Fix Both methods now emit `RuntimeWarning` on every call: (`update_or_create()` gets the matching "SELECT-then-UPDATE-or-INSERT" wording.) Fixed once, in the canonical `Model` classmethods (`aquilia/models/base.py`) — `Manager.get_or_create()`/`update_or_create()` and `Q.get_or_create()`/`update_or_create()` both forward into these, so all three public entry points are covered by the single change. **File:** `aquilia/models/base.py` Regression Tests — `tests/test_orm_concurrency_warnings.py` | Test | Coverage | |---|---| | `test_get_or_create_warns` | `RuntimeWarning` raised, message matches "not atomic" | | `test_update_or_create_warns` | Same, for `update_or_create()` | | `test_find_or_create_does_not_warn` | Confirms the race-free path stays silent |

### Code Examples
```python
# Before fix — all of these were ACCEPTED by .where(), i.e. NOT rejected
await User.objects.where("id = 1; DELETE FROM users")
await User.objects.where("id = 1; INSERT INTO users VALUES (...)")
await User.objects.where("id = 1 -- bypass rest of clause")

```

```python
# Before fix — query.py, Q.where()
_DANGEROUS_DDL = {"DROP ", "ALTER ", "TRUNCATE ", "EXEC ", "EXECUTE "}
for kw in _DANGEROUS_DDL:
    if kw in _upper:   # naive substring match
        raise SecurityFault(...)

# Before fix — query.py, Q.having() (different set, only when args is empty)
_DANGEROUS = {"DROP", "ALTER", "TRUNCATE", "EXEC", "EXECUTE", "--", ";"}

```

```python
# After fix — query.py
_UNSAFE_SQL_RE = re.compile(
    r"\b(DROP|ALTER|TRUNCATE|EXEC|EXECUTE|DELETE|INSERT|UPDATE|MERGE)\b|--|/\*|\*/|;",
    re.IGNORECASE,
)

def _reject_unsafe_clause(clause: str, *, code: str, context: str) -> None:
    match = _UNSAFE_SQL_RE.search(clause)
    if match:
        raise SecurityFault(
            code=code,
            message=f"Potentially unsafe {context} clause rejected: contains "
            f"'{match.group(0).strip()}'. Use parameterized values (?) for "
            f"user-supplied data.",
        )

```



---

## Framework Docs: releases/1.3.3/README.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-README`

Aquilia v1.3.3 Release Notes — "Analytical Depths" Aquilia v1.3.3 is a focused ORM release delivering three long-awaited analytical query capabilities — **Window Functions**, **CTEs**, and **Recursive CTEs** — implemented as first-class AST nodes in the expression system, not thin raw-SQL wrappers. The release also ships two ORM bug fixes discovered and verified during a production-grade audit of the models layer, plus a follow-up round of security hardening and four new enterprise field types (**MoneyField**, **EncryptedField**, **PointField**/**GeometryField**, **GenericForeignKey**) driven by a senior-engineer assessment of the ORM. --- Table of Contents 1. [Window Functions](window_functions.md) - Ranking, distribution, and offset window functions - Aggregate windows (running totals, moving averages) - PARTITION BY, ORDER BY, and frame clauses 2. [CTEs — Common Table Expressions](cte.md) - Non-recursive CTEs - Multiple CTEs and dependency chaining 3. [Recursive CTEs](recursive_cte.md) - Tree traversal and hierarchical queries - Anchor/recursive API - UNION vs UNION ALL 4. [Bug Fixes](bugfixes.md) - UUIDField(auto=True) NULL primary key - Transaction nesting depth tracker - Controller `self.render()` TemplateEngine resolution failure (Issue #59) 5. [Security & Concurrency Hardening](security_hardening.md) - Widened raw-SQL keyword blocklist on `Q.where()`/`Q.having()` - `get_or_create()`/`update_or_create()` non-atomic `RuntimeWarning` 6. [Enterprise Field Types](enterprise_fields.md) - `MoneyField` — currency-aware decimal storage - `EncryptedField` — transparent field-level encryption - `PointField` / `GeometryField` — portable GeoJSON spatial fields - `GenericForeignKey` — polymorphic relations without a ContentType table 7. [Backend Compatibility Matrix](backends.md) 8. [Migration Guide](migration.md) --- Quick Examples Window: rank users by score inside each country Window: running total of sales CTE: active users summary Recursive CTE: folder tree MoneyField + EncryptedField: a wallet with a secret GenericForeignKey: comments on anything Race-free upsert (and why get_or_create() now warns) --- What Changed New modules | Module | Purpose | |---|---| | `aquilia.models.window` | `Window`, all window functions, `FrameBound`, `WindowFrame`, `FrameType` | | `aquilia.models.cte` | `CTE`, `RecursiveCTE`, `CTEReference`, `CTECol` | Q chain methods added | Method | Purpose | |---|---| | `Q.cte(name)` | Create a named CTE from this queryset | | `Q.with_cte(*ctes)` | Register CTEs into the query's WITH clause | | `Q.recursive_cte(name, anchor, recursive, *, union_all)` | Build + register a recursive CTE | Expression system additions (`aquilia.models.window`) `Window`, `Rank`, `DenseRank`, `RowNumber`, `Ntile`, `Lag`, `Lead`, `FirstValue`, `LastValue`, `NthValue`, `FrameType`, `FrameBound`, `WindowFrame` All available via `from aquilia.models import Window, Rank, ...` New field types (`aquilia.models`) | Field | Extends | Purpose | |---|---|---| | `MoneyField` | `DecimalField` | Currency-aware precise decimal storage | | `EncryptedField` | `EncryptedMixin` + `TextField` | Transparent field-level encryption at rest | | `PointField` / `GeometryField` | `JSONField` | Portable GeoJSON-backed spatial data | | `GenericForeignKey` | *(none — not a `Field`)* | Polymorphic relation via a model-label + PK column pair | See [Enterprise Field Types](enterprise_fields.md) for full usage. --- Fixes Shipped | Issue | Root cause | Fix | |---|---|---| | `UUIDField(auto=True)` inserts NULL | `setdefault` no-op on pre-populated `kwargs` dict | Explicit `UNSET` sentinel check | | Transaction depth leak / `id()` contamination | `WeakValueDictionary` integer keys never freed; `id()` reuse gives new task stale depth | Replaced with `contextvars.ContextVar[int]` | | `Q.where()`/`Q.having()` raw-SQL blocklist incomplete/inconsistent | Two separate hand-maintained keyword sets, substring (not word-boundary) matching | One shared word-boundary regex guard; widened keyword set | | `get_or_create()`/`update_or_create()` race silently possible | SELECT-then-INSERT/UPDATE with no runtime signal | `RuntimeWarning` pointing at `find_or_create()` | | `EncryptedMixin.to_db()` `TypeError` on real save | Missing `dialect` keyword parameter, never exercised through `Model.save()` | Added `dialect: str = "sqlite"` param | See [Security & Concurrency Hardening](security_hardening.md) for full root-cause detail on the last three.

### Code Examples
```python
from aquilia.models import Window
from aquilia.models.window import Rank

users = await User.objects.annotate(
    rank=Window(
        Rank(),
        partition_by=["country"],
        order_by="-score",
    )
).all()

for u in users:
    print(u.name, u.rank)

```

```python
from aquilia.models import Sum, Window

sales = await Sale.objects.annotate(
    running_total=Window(
        Sum("amount"),
        order_by="created_at",
    )
).order("created_at").all()

```

```python
active_cte = User.objects.filter(is_active=True).cte("active_users")

result = await (
    User.objects
    .with_cte(active_cte)
    .filter(role="admin")
    .all()
)

```



---

## Framework Docs: releases/1.3.3/enterprise_fields.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-enterprise_fields`

Enterprise Field Types — Aquilia v1.3.3 Four new field types close the gap flagged by a senior-engineer assessment of the ORM's field system: currency-aware money storage, transparent field-level encryption, portable spatial data, and polymorphic relations. All four are additive, require no new dependencies, and needed no changes to schema-generation or migration dialect-mapping code — each subclasses an existing field whose `isinstance()`-based SQL-type dispatch already matches subclasses. --- MoneyField `DecimalField` plus a `currency` code. Precision/storage behavior is identical to `DecimalField` — values are stored as `str()` (never a binary float), avoiding rounding error entirely. **Signature:** - `currency` is metadata carried on the *field*, not encoded per-row — if you need a different currency per row, pair `MoneyField` with a sibling `CharField`/`choices` column and read both. - Only the 3-uppercase-letter *shape* is validated (`^[A-Z]{3}$`), not membership in the real ISO 4217 table — a well-formed but unrecognized code (e.g. a test/private currency) is accepted on purpose. Raises `FieldValidationError` on construction for a malformed code (`"dollars"`, `"US"`, `"usd"`). - `deconstruct()` includes `currency` for migration diffing. --- EncryptedField Transparent application-layer encryption at the storage boundary — built on the existing `EncryptedMixin` (`aquilia/models/fields/mixins.py`), wrapping `TextField`. Plaintext is validated as a normal `TextField` on assignment; encryption/decryption happens only at `to_db()`/`to_python()` (i.e., only on the wire to/from the database). **Encryption backend priority** (see `EncryptedMixin`'s docstring for full detail): 1. **Custom callables** — `EncryptedField.configure_encryption(encrypt_fn, decrypt_fn)` 2. **Fernet** (`cryptography` package, if installed) — `configure_encryption_key(key)` 3. **AES-256-GCM stdlib fallback** — same `configure_encryption_key(key)` call, used automatically when `cryptography` isn't installed. No extra packages required. 4. **Base64 placeholder** — used only if no backend was ever configured. **Not encryption** — trivially reversible. Emits a loud `UserWarning` every time it's hit specifically so this can't go unnoticed in production. > **Security note:** call `configure_encryption_key()` or > `configure_encryption()` before any real secret is ever saved. If you see > the `UserWarning` about base64 fallback in your logs, no backend has been > configured and nothing is actually encrypted yet. **Bug fixed while shipping this:** `EncryptedMixin.to_db()` previously didn't accept the `dialect` keyword argument that every real `Model.save()` call site passes (`field.to_db(value, dialect=dialect)`) — so a real encrypted field would `TypeError` the moment it was saved through a model. `EncryptedMixin` was, until now, only ever exercised standalone in tests, never through an actual `Model.save()`. `to_db()` now accepts (and ignores — encryption doesn't vary per dialect) `dialect`. --- PointField / GeometryField Portable, GeoJSON-backed spatial fields — both subclass `JSONField` and store data as `TEXT`/`JSONB` exactly like any other JSON value. No PostGIS extension, no native geometry column type, no new dependency. This trades native spatial indexing/query operators for zero-setup portability across SQLite/PostgreSQL/MySQL. - **`PointField`** requires `{"type": "Point", "coordinates": [lon, lat]}` — exactly 2 numeric coordinates. Raises `FieldValidationError` for any other shape or geometry type. - **`GeometryField`** accepts any standard GeoJSON geometry type: `Point`, `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon`, `GeometryCollection` — validated against `{"type": <one of those>, "coordinates": [...]}`. > **When you outgrow this:** if you need native spatial indexes (PostGIS > `GIST`, MySQL `SPATIAL`), spatial query operators (`ST_Contains`, > `ST_Distance`), or geometry validation beyond well-formed GeoJSON shape, > you'll want a dedicated PostGIS/spatial-extension integration — that's > out of scope for this JSON-backed field pair, which optimizes for > portability and zero setup. --- GenericForeignKey A polymorphic relation to *any* registered model — Django's "virtual field" pattern. Unlike `ForeignKey`, it doesn't own a database column of its own: you declare two real columns yourself (a model-label column and a stringified-PK column), and `GenericForeignKey` resolves between them. **Why this isn't a transparent attribute (unlike Django's `GenericForeignKey`):** Aquilia is async-native — there's no way to do a lazy synchronous DB fetch on plain attribute access (`comment.target`) the way Django's sync ORM can. Resolution is instead an explicit async method: **Why no `ContentType` model:** Django's `GenericForeignKey` looks up a `content_type_id` against a database-backed `ContentType` table. Aquilia reuses the already-existing, in-memory `ModelRegistry.get(label)` lookup — the same primitive `For

### Code Examples
```python
from aquilia.models import (
    MoneyField, EncryptedField, PointField, GeometryField, GenericForeignKey,
)

```

```python
from aquilia.models import Model, MoneyField

class Order(Model):
    table = "orders"

    total = MoneyField(max_digits=12, decimal_places=2, currency="USD")
    shipping = MoneyField(max_digits=8, decimal_places=2, currency="EUR", default="0.00")

```

```python
order = await Order.create(total="149.99")
order.total          # Decimal('149.99')
order.currency if hasattr(order, "currency") else Order.total.currency  # "USD" — the field's currency, not per-row

```



---

## Framework Docs: releases/1.3.3/window_functions.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.3-window_functions`

Window Functions — Aquilia v1.3.3 Window functions compute a value for each row relative to a *window* of related rows, without collapsing rows the way `GROUP BY` aggregates do. They appear as `FUNC() OVER (PARTITION BY ... ORDER BY ...)` in SQL. --- Core API `Window(expression, *, partition_by, order_by, frame)` The top-level wrapper. Takes any window function or aggregate and attaches an `OVER (...)` clause to it. **Arguments** | Argument | Type | Description | |---|---|---| | `expression` | `Expression` | Window function (`Rank()`) or aggregate (`Sum("amount")`) | | `partition_by` | `str \| F \| list[str \| F] \| None` | Columns to partition by | | `order_by` | `str \| OrderBy \| list \| None` | Ordering inside the window (prefix `-` for DESC) | | `frame` | `WindowFrame \| None` | Optional ROWS/RANGE frame clause | --- Window Functions Ranking Generated SQL: Distribution Offset Functions Value Functions Aggregate Windows (Running Totals / Moving Averages) Any existing Aquilia aggregate works inside `Window(...)`: --- Frame Clauses Control exactly which rows fall in the window via `WindowFrame`. Generated SQL: --- Practical Examples Leaderboard with rank per category > Note: filtering on window annotations requires wrapping in a subquery on > databases that evaluate `WHERE` before `SELECT`. Use `values()` + Python > filtering, or a CTE, for cross-engine safety. 7-day moving average Year-over-year comparison with Lag --- Backend Compatibility | Feature | SQLite | PostgreSQL | MySQL | |---|---|---|---| | `RANK`, `DENSE_RANK`, `ROW_NUMBER` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | | `NTILE` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | | `LAG`, `LEAD` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | | `FIRST_VALUE`, `LAST_VALUE` | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | | `NTH_VALUE` | ≥ 3.25 | ≥ 11 | ≥ 8.0.2 | | Frame clauses | ≥ 3.25 | ≥ 8.4 | ≥ 8.0 | | `GROUPS` frame type | ≥ 3.28 | ≥ 11 | — |

### Code Examples
```python
from aquilia.models import Window, Sum
from aquilia.models.window import Rank, DenseRank, RowNumber

```

```python
# RANK() — gaps after ties
rank = Window(Rank(), partition_by=["dept"], order_by="-salary")

# DENSE_RANK() — no gaps
dense = Window(DenseRank(), partition_by=["dept"], order_by="-salary")

# ROW_NUMBER() — unique sequential integers
row_num = Window(RowNumber(), order_by="created_at")

```

```python
sql
RANK() OVER (PARTITION BY "dept" ORDER BY "salary" DESC)
DENSE_RANK() OVER (PARTITION BY "dept" ORDER BY "salary" DESC)
ROW_NUMBER() OVER (ORDER BY "created_at" ASC)

```



---

## Framework Docs: releases/1.3.2/compilation.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-compilation`

Spec Compilation & Schema Inference Specula features a compiler-integrated OpenAPI 3.1.0 specification engine (`SpeculaBuilder`). Instead of scanning source files at startup, it introspects Aquilia's compiled routing topology in memory, extracting schemas, bindings, parameters, and outputs. --- Python-to-JSON Schema Mapping When generating schema objects, Specula inspects standard type hints and maps them to their OpenAPI 3.1.0 JSON Schema equivalents. Specula is fully compliant with the OpenAPI 3.1.0 specification: * **Option types** use `oneOf` blocks combined with `{"type": "null"}` instead of the deprecated `nullable` property. * **Complex Python structures** map cleanly to nested schemas. Mapping Reference Table | Python Type Hint | JSON Schema Equivalent | | :--- | :--- | | `str` | `{"type": "string"}` | | `int` | `{"type": "integer"}` | | `float` | `{"type": "number", "format": "double"}` | | `bool` | `{"type": "boolean"}` | | `bytes` | `{"type": "string", "format": "binary"}` | | `None` / `type(None)` | `{"type": "null"}` | | `Optional[T]` / `T \| None` | `{"oneOf": [{"type": T_schema}, {"type": "null"}]}` | | `list[T]` / `List[T]` | `{"type": "array", "items": T_schema}` | | `dict[str, T]` / `Dict[str, T]` | `{"type": "object", "additionalProperties": T_schema}` | | `tuple[T1, T2]` | `{"type": "array", "prefixItems": [T1_schema, T2_schema], "minItems": 2, "maxItems": 2}` | | `Contract` / `Model` | `{"$ref": "#/components/schemas/Name"}` | --- Request Body Inference Strategies Specula resolves request payloads through a 5-tier inference engine, prioritizing explicit developer configurations over implicit code analysis. 1. The `request_contract` Parameter If a route decorator declares a validation contract directly, the builder generates a reference schema: 2. Contract Parameter Type Hints If a route handler receives a parameter type-hinted with an Aquilia `Contract` class, it is automatically mapped as the JSON body payload: 3. Explicit `Body` Metadata Annotations If a parameter is annotated using standard Python type annotations with `Body()`, it is mapped to a properties-based object payload: 4. Docstring Body Mappings The builder parses Google-style docstrings, extracting raw examples from `Body:` headers: 5. Source Code Introspection As a fallback, Specula scans the compiled handler source code for extraction patterns: * Finding `await ctx.json()` infers a generic `application/json` object. * Finding `await ctx.form()` infers an `application/x-www-form-urlencoded` form. --- Response Shapes Resolution Specula automatically maps success and error response channels. Success Shapes 1. **Model / Contract Mappings**: Declaring `response_model` or `response_contract` registers the corresponding schema (input contracts map with `Input` suffix, output contracts map directly) and binds them under status code `2xx`. 2. **Standard Output Fallbacks**: If no return contract is specified, Specula inspects handler code: * Calls to `Response.json(...)` default to `application/json`. * Calls to `Response.html(...)` or template rendering functions default to `text/html`. * References to `SSEResponse(...)` default to `text/event-stream`. Error Shapes * **Raises Docstring Section**: Specula compiles exception details declared in Google-style docstrings into typed status responses: Specula compiles this raises annotation into a structured `404 Not Found` response returning the standard `AquiliaError` schema. * **Auto-Validation Errors**: All write routes (`POST`, `PUT`, `PATCH`) automatically carry a default `422 Unprocessable Entity` response mapping returning the structured `AquiliaValidationError` schema.

### Code Examples
```python
@POST("/users", request_contract=UserCreateContract)
async def create_user(self, ctx: RequestCtx): ...

```

```python
@POST("/users")
async def create_user(self, ctx: RequestCtx, payload: UserCreateContract): ...

```

```python
@POST("/items")
async def create_item(self, ctx: RequestCtx, amount: Annotated[int, Body()] = 1): ...

```



---

## Framework Docs: releases/1.3.2/engine.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-engine`

Unified Resolution Engine Before v1.3.2, Aquilia ran **two** resolution engines: the `Container` (constructor injection, scopes, caching) and a separate FastAPI-`Depends`-style `RequestDAG` (inline `Dep()` injection). They duplicated cycle detection, caching, and teardown logic. v1.3.2 folds them into **one engine owned by the container**. What Changed `RequestDAG` is now a thin compatibility shim. Its public API is unchanged and existing code keeps working: All resolution state — the request-local cache, generator teardowns, and the resolving-set — now lives on the container. The real work moved to `Container.resolve_dep(dep, param_type, request=None)`. The practical benefit: inline `Dep()` dependencies and constructor-injected services now share **one deduplicated graph**. A `get_db` dependency awaited by two sibling `Dep()`s and a constructor-injected repository resolves exactly once per request. --- Resolution Guarantees The unified engine provides, in one place: * **Sub-dependency dedup** — a diamond (A→C, B→C) resolves C once. A shared in-flight `Future` lets concurrent sibling branches await the same result instead of recomputing. * **Parallel independent branches** — sub-dependencies of a `Dep` resolve concurrently via `asyncio.gather` when there is more than one. * **Generator teardown (LIFO)** — a `yield`-style dependency registers its teardown, which runs on `container.shutdown()` before container finalizers. * **True-cycle detection** — a task-local ancestor chain distinguishes a real self-cycle (raises `DIResolutionFault` "Circular…") from a benign diamond (awaits the shared future). Because `contextvars` copy per asyncio task, parallel `gather()` branches each see their own ancestor chain. --- New Container Methods `add_dependency_link(app_name, container)` The runtime counterpart to a manifest's `depends_on`. When a token is missing locally (and up the parent chain), resolution falls through to the linked sibling app container. The owning app instantiates and caches its own singletons exactly once. Wired automatically by the runtime from `depends_on` declarations. A cross-link cycle (A→B→A) raises `DependencyCycleError` via a task-local guard, instead of deadlocking. An undeclared cross-app dependency still raises `ProviderNotFoundError`. `create_child(scope="app", *, own_lifecycle=True)` A generic hierarchical child container (copy-on-write provider dict; parent singletons resolved once at the owning level). Use it for per-tenant containers or multi-level scope trees. Distinct from `create_request_scope()`, which is specialized for the per-request hot path. `await replace_provider(token, provider, *, tag=None)` Production-safe atomic hot-swap. Copy-on-write safe (forks a shared provider dict first) and evicts the cached instance so the next resolution builds from the new provider. In-flight holders of the old instance are unaffected. Distinct from the test-only `override_container`. --- Production Hardening * **Persistent sync loop** — `Container.resolve()` and lazy proxies now drive the async path on one persistent per-thread event loop instead of creating and closing a fresh loop on every call. 50 sync `resolve()` calls create exactly one loop. Calling the sync path from inside a running loop raises `DIResolutionFault` (deadlock guard) — `await resolve_async()` instead. * **Bounded pool waiters** — `PoolProvider(max_waiters=…)` (default from `pool_max_waiters`) fast-fails a burst against an exhausted pool with `DIResolutionFault` instead of thundering-herd queueing. * **In-flight dedup** — under `parallel_resolution`, concurrent resolvers of the same uncached cacheable token share one instance, preserving the singleton/app/request identity guarantee. * **Parallel resolution safety** — each concurrent branch gets a forked `ResolveCtx` (a copy of the cycle-guard stack), so parallelism cannot corrupt the shared resolution stack.

### Code Examples
```python
dag = RequestDAG(container, request)
value = await dag.resolve(dep, param_type)   # delegates to container.resolve_dep(...)
await dag.teardown()                         # delegates to container._run_dep_teardowns()

```

```python
from typing import Annotated
from aquilia.di import Dep

async def get_db():
    print("open");  yield "SESSION";  print("close")

async def get_repo(db: Annotated[str, Dep(get_db)]):  return {"db": db}
async def get_auth(db: Annotated[str, Dep(get_db)]):  return {"db": db}

@GET("/dashboard")
async def dashboard(
    self, ctx,
    repo: Annotated[dict, Dep(get_repo)],
    auth: Annotated[dict, Dep(get_auth)],
):
    return {"repo": repo, "auth": auth}
# "open" prints ONCE (dedup); "close" runs after the response (LIFO teardown).

```

```python
# billing's container may resolve auth-owned providers because
# billing's manifest declares depends_on=["auth"].
billing_container.add_dependency_link("auth", auth_container)

```



---

## Framework Docs: releases/1.3.2/extensibility.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-extensibility`

Extensibility: Interceptors, Plugins & Conditionals Aquilia v1.3.2 adds three first-class extension points to the DI container, each gated by a `DISettings` flag so they cost nothing when unused. --- 1. Provider Interceptors (AOP) Interceptors wrap a provider's **instantiation** with around-advice — logging, timing, tracing, caching — without touching the service class. Wrap any provider with `intercept()`. **Ordering.** Interceptors run first = outermost. `intercept(P, A, B)` yields the chain `A(in) → B(in) → B(out) → A(out)`. Call `nxt()` to proceed; skip it to short-circuit with your own object. The public API — `ProviderInterceptor` (protocol), `InterceptingProvider`, `InterceptContext`, `intercept()` — is exported from `aquilia.di`. The wrapped `InterceptingProvider` mirrors the inner provider's token, scope, and tags. Wrapping with an empty interceptor list raises `DIFault` (`DI_NO_INTERCEPTORS`). --- 2. DI Plugins A `DIPlugin` hooks into registry construction — auto-register a family of providers, observe every registration, or inspect built containers. Honoured during boot when `enable_plugins` is on (default). **Failure isolation.** A plugin hook that raises is logged and skipped — it never crashes boot. Manage the registry with `unregister_plugin(name)`, `get_plugins()`, and `clear_plugins()` (test teardown). Plugins are deduplicated by `.name`. `get_plugins()` returns `[]` when `enable_plugins` is off. --- 3. Conditional Providers Gate registration on the environment or config — the Spring `@Profile` / `@ConditionalOnProperty` equivalent. Honoured when `enable_conditional_providers` is on (default). `ConditionContext` is a frozen dataclass with two fields — `env` (the active environment, from `AQUILIA_ENV` or config) and `config` — plus two helpers: `get(path, default)` for dot-path lookups and `is_env(*names)` for case-insensitive env matching. **Safe by default.** A service with no condition always registers. If a predicate raises, the service is skipped (treated as `False`) and boot continues — a bad predicate never crashes startup. Use `should_register(target, ctx)` to evaluate a predicate manually.

### Code Examples
```python
from aquilia.di import ProviderInterceptor, intercept, ClassProvider

class TimingInterceptor(ProviderInterceptor):
    async def around_instantiate(self, ctx, nxt):
        import time
        start = time.perf_counter()
        obj = await nxt()                    # proceed to real instantiation
        print(f"built {ctx.meta.name} in {(time.perf_counter()-start)*1e6:.1f}us")
        return obj

provider = intercept(ClassProvider(UserService, scope="app"), TimingInterceptor())
container.register(provider)

```

```python
from aquilia.di import DIPlugin, register_plugin, ClassProvider

class AuditPlugin(DIPlugin):
    name = "audit"                       # stable id — re-registering replaces

    def on_registry_build(self, registry):
        # after manifests load, before the graph is built
        registry.add_provider(ClassProvider(AuditLogger, scope="app"))

    def on_provider_registered(self, container, provider):
        ...                              # fires per register() call

    def on_container_built(self, container):
        ...                              # fires once each app container is built

register_plugin(AuditPlugin())

```

```python
from aquilia.di import service, conditional, ConditionContext

# via the when= parameter on @service
@service(when=lambda c: c.env == "prod")
class RealPaymentGateway: ...

@service(when=lambda c: c.env != "prod")
class FakePaymentGateway: ...

# standalone @conditional — matches prod OR staging (case-insensitive)
@conditional(lambda c: c.is_env("prod", "staging"))
class MetricsExporter: ...

# property-based: dot-path lookup into config
@conditional(lambda c: c.get("cache.backend") == "redis")
class RedisCacheWarmup: ...

```



---

## Framework Docs: releases/1.3.2/di-settings.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-di-settings`

DI Settings & Configuration In Aquilia v1.3.2, every runtime knob for the dependency-injection container lives in a single typed, immutable object: `DISettings`. The subsystem historically read a couple of loose `os.environ` flags (e.g. strict-scope enforcement); those are gone. You now configure the container the same way you configure every other subsystem — through a config block in `workspace.py`. The `DISettings` Object `DISettings` is a frozen, slotted dataclass defined in `aquilia.di.settings`. Every field maps 1:1 to a key under the `di` config section. | Field | Default | Purpose | |---|---|---| | `scope_enforcement` | `"warn"` | Captive-dependency handling: `"warn"` logs, `"raise"` raises `ScopeViolationError`, `"off"` skips the check. | | `parallel_resolution` | `False` | Resolve independent constructor dependencies concurrently via `asyncio.gather`. | | `diagnostics_enabled` | `False` | Emit `RESOLUTION_START/SUCCESS/FAILURE` diagnostic events per resolve. | | `disposal_strategy` | `"lifo"` | Finalizer ordering: `"lifo"`, `"fifo"`, or `"parallel"`. | | `hook_timeout_seconds` | `30.0` | Per-hook timeout for startup/shutdown lifecycle hooks. | | `pool_acquire_timeout_seconds` | `30.0` | Default pool acquire timeout. | | `pool_max_waiters` | `None` | Cap on concurrent waiters against an exhausted pool (fast-fail). `None` = unbounded. | | `type_key_cache_max` | `8192` | Upper bound on the global type→key cache before a wholesale flush. | | `enable_conditional_providers` | `True` | Honour `@conditional` / `when=` predicates during registration. | | `enable_plugins` | `True` | Run registered `DIPlugin` hooks during registry build. | | `strict_service_registration` | `False` | Fail-fast at boot when a service fails to register, instead of logging and continuing. | Two derived properties support hot-path checks: `strict_scopes` (True when `scope_enforcement == "raise"`) and `scope_check_enabled` (True unless `"off"`). --- Configuring DI in `workspace.py` Add a `di` block to your environment config. It subclasses `AquilaConfig.DI`, and the server reads it at boot and installs it via `configure_di()` automatically. `aq init` now scaffolds these blocks in generated projects: `DevEnv` enables diagnostics, `ProdEnv` sets `scope_enforcement="raise"` and `parallel_resolution=True`. --- Programmatic Configuration In tests or scripts, configure the container directly. Until `configure_di()` runs, a permissive default applies, so importing the DI system in isolation needs no setup. `configure_di()` is last-call-wins and also propagates `type_key_cache_max` into the core module's cache bound. --- Validation & `DIConfigFault` Invalid values raise `DIConfigFault` (code `DI_CONFIG_INVALID`) at construction, so bad configuration surfaces at boot rather than at first resolution: `DISettings.from_mapping(data)` builds settings from a `di` config dict (or attribute object, or `None`) and ignores unknown keys for forward compatibility. --- New Boot-Time Faults Two configuration-driven faults now surface at service registration: * **`INVALID_SERVICE_SCOPE`** — a manifest declares an unknown scope (e.g. `"singelton"`). Always fatal; the message lists the valid scopes. * **`SERVICE_REGISTRATION_FAILED`** — a service fails to import/construct. Fatal only when `strict_service_registration=True`; otherwise logged and skipped so the app still boots.

### Code Examples
```python
from dataclasses import dataclass

@dataclass(frozen=True, slots=True)
class DISettings:
    scope_enforcement: str = "warn"          # "warn" | "raise" | "off"
    parallel_resolution: bool = False
    diagnostics_enabled: bool = False
    disposal_strategy: str = "lifo"          # "lifo" | "fifo" | "parallel"
    hook_timeout_seconds: float = 30.0
    pool_acquire_timeout_seconds: float = 30.0
    pool_max_waiters: int | None = None      # None = unbounded
    type_key_cache_max: int = 8192
    enable_conditional_providers: bool = True
    enable_plugins: bool = True
    strict_service_registration: bool = False

```

```python
from aquilia import AquilaConfig

class BaseEnv(AquilaConfig):
    class di(AquilaConfig.DI):
        scope_enforcement   = "warn"     # "warn" | "raise" | "off"
        parallel_resolution = False

class DevEnv(BaseEnv):
    class di(BaseEnv.di):
        diagnostics_enabled = True       # trace every resolution in dev

class ProdEnv(BaseEnv):
    class di(BaseEnv.di):
        scope_enforcement   = "raise"    # fail-fast on captive deps
        parallel_resolution = True       # resolve independent deps concurrently
        pool_max_waiters    = 256        # fast-fail an exhausted pool

```

```python
from aquilia.di import DISettings, configure_di, get_di_settings, reset_di_settings

configure_di(DISettings(scope_enforcement="raise", parallel_resolution=True))

assert get_di_settings().strict_scopes is True

# Test teardown — restore permissive defaults
reset_di_settings()

```



---

## Framework Docs: releases/1.3.2/observatory.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-observatory`

Specula Observatory UI & Integration The Specula Observatory is a built-in interactive dashboard served natively by Aquilia at `/specula`. It provides a CDN-free developer sandbox that works entirely offline, inline-cached, and features hot-reload awareness. Workspace Integration Specula is registered at the workspace level inside `workspace.py`. You configure it using the `Integration.specula(...)` builder method or by importing and instantiating `SpeculaIntegration` directly: --- Configuration Reference (`SpeculaConfig`) When you configure Specula, your parameters map to the `SpeculaConfig` dataclass. The primary settings available are: | Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | **Info / Branding** | | | | | `title` | `str` | `"Aquilia API"` | Name of the API, visible in the UI header and spec exports. | | `version` | `str` | `"1.0.0"` | The current API release version. | | `description` | `str` | `""` | Detailed description of the API. | | `ui_theme` | `str` | `"auto"` | `"auto"` (matches system preferences), `"light"`, or `"dark"`. | | `ui_primary_color`| `str` | `"#22c55e"` | Hex code for branding the main interface buttons and tags. | | **URL Paths** | | | | | `ui_path` | `str` | `"/specula"` | Browser path to view the Observatory HTML dashboard. | | `json_path` | `str` | `"/specula/spec.json"`| JSON endpoint serving the raw OpenAPI 3.1.0 spec. | | `yaml_path` | `str` | `"/specula/spec.yaml"`| YAML endpoint serving the raw OpenAPI 3.1.0 spec. | | `stream_path` | `str` | `"/specula/stream"`| SSE stream pushing route updates to the UI. | | `mock_path` | `str` | `"/specula/mock"` | Endpoint path for the mock server router. | | **Feature Toggles** | | | | | `enabled` | `bool` | `True` | Master toggle to enable or disable Specula routes. | | `include_internal`| `bool` | `False` | Whether routes matching `/_*` are included in the spec. | | `detect_security` | `bool` | `True` | Scan route guards and decorators to construct security schemes. | | `mock_server_enabled`| `bool` | `False` | Set `True` to enable schema-synthesized mock responses. | | `spec_cache_ttl` | `int` | `60` | In-memory cache duration (in seconds) for compiled spec payloads. | --- Hot-Reloading SSE Stream (`/specula/stream`) During development, Aquilia runs with file watchers. When you modify controller code, the worker process reloads. Specula exposes a native ASGI Server-Sent Events (SSE) stream endpoint at `/specula/stream`. When the dashboard is loaded in a browser, it subscribes to this stream. When a reload happens, the server pushes an invalidation event down the pipe: The Observatory frontend listens to this event and immediately fetches the newly compiled specification and routes dynamically, refreshing the client view with zero hard refreshes. --- Production Security Locks By default, the Specula Observatory is fully open. In production environments, you can lock access down to authenticated users with specific roles: When `docs_auth_required` is enabled, the Specula controller inspects the request context using the configured `AuthMiddleware` pipeline. If the visitor lacks the required roles, they receive a `403 Forbidden` response.

### Code Examples
```python
# workspace.py
from aquilia.workspace import Workspace
from aquilia.integrations import Integration, SpeculaIntegration

workspace = (
    Workspace("user-portal")
    
    # Style A: Fluent Integration helper
    .integrate(Integration.specula(
        title="User Portal API",
        version="1.4.0",
        ui_theme="dark"
    ))
    
    # Style B: Direct Instantiation (provides static checks and autocomplete)
    # .integrate(SpeculaIntegration(
    #     title="User Portal API",
    #     version="1.4.0",
    #     ui_theme="dark"
    # ))
)

```

```python
{"event": "update", "data": {"status": "invalidated", "version": "2.0.0"}}

```

```python
workspace.integrate(Integration.specula(
    title="Corporate Core API",
    docs_auth_required=True,
    docs_roles=["admin", "ops-team"]
))

```



---

## Framework Docs: releases/1.3.2/migration.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-migration`

Migration Guide: v1.3.1 to v1.3.2 Aquilia v1.3.2 introduces **Specula** (replacing the legacy OpenAPI generator) and rewrites the dependency-injection subsystem while keeping public core APIs backward compatible. This guide covers the deprecations, configuration changes, and migration steps for both subsystems. --- Part A: OpenAPI to Specula Migration Aquilia v1.3.2 deprecates and removes the old static OpenAPI/Swagger engine. 1. Configuration & Integration Upgrades The old `OpenAPIIntegration` has been replaced by `SpeculaIntegration`. In your `workspace.py`, update your registrations: Legacy Style (Removed) New Style (Active) Parameter Mapping Table | Legacy OpenAPI Option | New Specula Option | Notes | | :--- | :--- | :--- | | `docs_path` | `ui_path` | Default changes from `/docs` to `/specula`. | | `openapi_json_path` | `json_path` | Default changes from `/openapi.json` to `/specula/spec.json`. | | `redoc_path` | (Removed) | ReDoc is deprecated. Use the unified Specula dashboard. | | `swagger_ui_theme` | `ui_theme` | Values: `"auto"`, `"light"`, `"dark"`. | | `swagger_ui_config` | (Removed) | Replaced by direct dashboard configuration. | --- 2. Replaced Imports & Engines If you manually generated specs, update your imports and instantiation: --- 3. Redirects & Endpoint Updates The automatic redirects mapping legacy paths are no longer registered. Update links: * **Swagger UI Docs**: Old path `/docs` is replaced by `/specula`. * **ReDoc Docs**: Old path `/redoc` is deprecated. Use the unified `/specula` dashboard. * **JSON Specification**: Old path `/openapi.json` is replaced by `/specula/spec.json`. * **YAML Specification**: Specula now supports rendering YAML natively at `/specula/spec.yaml`. --- Part B: Dependency Injection Subsystem Migration 4. Move DI Flags into the `di` Config Block The DI subsystem previously read loose environment flags (e.g. strict-scope enforcement) via `os.environ`. These are replaced by the typed `DISettings` object, configured through a `di` block in `workspace.py`. Before (v1.3.1) — environment flags After (v1.3.2) — typed config Invalid values now fail fast at boot with `DIConfigFault` instead of being silently ignored. --- 5. `ServiceScope` Enum — Deprecated The `ServiceScope` Enum is deprecated in favor of plain string literals. Accessing any member (`ServiceScope.SINGLETON`) or calling the Enum emits a `DeprecationWarning` and will be removed in a future version. Before: After: Replace `ServiceScope.SINGLETON` → `"singleton"`, `.APP` → `"app"`, `.REQUEST` → `"request"`, `.TRANSIENT` → `"transient"`, `.POOLED` → `"pooled"`, `.EPHEMERAL` → `"ephemeral"`. String literals skip import-time namespace scanning and runtime attribute lookups. --- 6. `clear_request_container()` — Deprecated `clear_request_container()` is nesting-unsafe (it hard-resets the request container to `None`) and now emits a `DeprecationWarning`. `set_request_container()` and `RequestCtx.set_current()` now return a `Token`. Before: After: --- 7. `ModuleContainer` — Removed `ModuleContainer` has been removed. Cross-app resolution now uses link-based `Container.add_dependency_link()` instead of nested module containers. This is wired automatically by the runtime from each manifest's `depends_on` — no code change is required unless you instantiated `ModuleContainer` directly. If you declared cross-app dependencies, ensure they are listed in `depends_on`: An undeclared cross-app dependency raises `CrossAppDependencyError` at boot. --- 8. Behavioral Changes to Note These require no code change but alter runtime behavior: * **Unified engine** — inline `Dep()` dependencies and constructor-injected services now share one deduplicated resolution graph. `RequestDAG` remains as a thin shim over `container.resolve_dep()`; its public API is unchanged. * **Diagnostics are opt-in** — resolution events (`RESOLUTION_START/SUCCESS/FAILURE`) are emitted only when `diagnostics_enabled` is on. Turn it on in `DevEnv` to trace resolution. * **Provider shadowing** — a child container may now shadow a provider inherited from its parent. Only a genuine local re-registration of the same token+tag raises `PROVIDER_ALREADY_REGISTERED`. * **Structured faults** — the DI layer raises `DIFault` subclasses (with stable codes) rather than bare `ValueError`s. If you catch DI errors, catch `DIError` (or a specific subclass) instead of `ValueError`. * **Sync resolution in a running loop** — `Container.resolve()` and lazy proxies raise `DIResolutionFault` if called from inside a running event loop. In async code, always `await resolve_async()`. --- 9. New APIs Worth Adopting | API | Use it for | |---|---| | `DISettings` / `configure_di` | Typed, validated container configuration. | | `intercept()` / `ProviderInterceptor` | Around-advice on provider instantiation (timing, tracing). | | `DIPlugin` / `register_plugin` | Auto-registering providers and registry-build hooks. | | `@service(when=...)` / `@conditional` | Environment/feature-gated prov

### Code Examples
```python
# Replaced by Specula
workspace.integrate(Integration.openapi(
    title="Store API",
    docs_path="/apidocs",
    swagger_ui_theme="dark"
))

```

```python
from aquilia.integrations import SpeculaIntegration

# Option A: Direct class registration
workspace.integrate(SpeculaIntegration(
    title="Store API",
    ui_path="/apidocs",
    ui_theme="dark"
))

# Option B: Fluent helper
# workspace.integrate(Integration.specula(
#     title="Store API",
#     ui_path="/apidocs",
#     ui_theme="dark"
# ))

```

```python
# --- Legacy Imports (Removed) ---
# from aquilia.controller.openapi import OpenAPIConfig, OpenAPIGenerator
# config = OpenAPIConfig(title="API")
# spec = OpenAPIGenerator(config=config).generate(router)

# --- New Imports (Active) ---
from aquilia.specula.config import SpeculaConfig
from aquilia.specula.schema.builder import SpeculaBuilder

config = SpeculaConfig(title="API")
spec = SpeculaBuilder(config=config).build(router)

```



---

## Framework Docs: releases/1.3.2/README.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-README`

Aquilia v1.3.2 Release Notes — "Specula API Observatory & Deep Current" Aquilia v1.3.2 is a major release introducing **Specula** (a compiled, introspective ASGI dashboard and API exploration subsystem replacing legacy OpenAPI) alongside a ground-up rewrite of the dependency-injection subsystem (`aquilia.di`). --- Table of Contents Specula API Observatory 1. [Specula Observatory UI & Integration](observatory.md) * The new dashboard philosophy. * Integrating Specula via `Integration.specula(...)`. * UI branding and Server-Sent Events (SSE) live streams. 2. [Spec Compilation & Schema Inference](compilation.md) * The compiler-integrated `SpeculaBuilder`. * Python-to-JSON Schema type mapping. * Multi-strategy request body and response resolution. 3. [Automated Security & Clearance Detection](security.md) * Inferred security schemes from pipeline guards. * Integrated authorization clearance level detection. * Extended metadata (`x-specula-security`) vendor extensions. 4. [Mock Server & Collection Exports](mock_exports.md) * Interactive mocking engine at `/specula/mock`. * Schema synthesis with configurable recursion depth limits. * Dynamic exports for Postman v2.1 and Insomnia v4. Dependency Injection Subsystem ("Deep Current") 5. [DI Settings & Configuration](di-settings.md) * The new typed `DISettings` object and the `AquilaConfig.DI` config block. * Scope enforcement, parallel resolution, diagnostics, disposal, and pooling knobs. * `configure_di`, `get_di_settings`, `reset_di_settings`, and `DIConfigFault`. 6. [Unified Resolution Engine](engine.md) * Folding `RequestDAG` into the container — one engine for the whole framework. * Sub-dependency dedup, parallel branches, generator teardown, cross-link cycle detection. * New `Container` methods: `add_dependency_link`, `create_child`, `replace_provider`, `resolve_dep`. 7. [Extensibility: Interceptors, Plugins & Conditionals](extensibility.md) * Provider interceptors (`ProviderInterceptor`, `intercept`) for instantiation around-advice. * DI plugins (`DIPlugin`, `register_plugin`) for registry-build hooks. * Conditional providers (`@service(when=...)`, `@conditional`, `ConditionContext`). Migration Guide 8. [Migration Guide](migration.md) * OpenAPI to Specula migration. * DI settings, deprecations, and behavioral changes. --- Key Subsystem Improvements Specula API Observatory 1. **Compilation over Code Scanning**: No more parsing source files or class matching at runtime. Specula extracts endpoint specs directly from Aquilia's compiled in-memory ASGI routing topology. 2. **Developer Reactivity**: Hot-reloading modules push Specula spec invalidations down active Server-Sent Events (SSE) connections, immediately refreshing the developer's dashboard. 3. **Simulated Sandbox**: Frontends can start testing integration before the backend endpoints are written. The mock server synthesizes response payloads matching the exact JSON schemas defined in Contracts or ORM Models. 4. **Complete Security Transparency**: Exposes exact pipeline guards, role requirements, and AccessLevel clearance levels to ensure complete architectural observability. Dependency Injection Rewrite 1. **One Engine**: Collapse the container resolver and the FastAPI-`Depends`-style `RequestDAG` into a single engine owned by the container, so inline `Dep()` dependencies and constructor-injected services share one deduplicated graph. 2. **Typed Configuration**: Replace loose `os.environ` flags with an immutable, validated `DISettings` object, configured through `workspace.py` like every other subsystem. Bad configuration fails fast at boot with `DIConfigFault`. 3. **Extensibility**: Add first-class AOP (interceptors), registry-build hooks (plugins), and environment/feature-gated registration (conditional providers) — the Spring `@Profile` / `@ConditionalOnProperty` equivalent. 4. **Production Hardening**: Persistent per-thread sync loop (no throwaway loop per call), bounded pool waiters (fast-fail under overload), in-flight dedup for concurrent resolvers, and cross-app cycle detection that raises instead of deadlocking. 5. **Structured Faults**: Every DI failure raises a `DIFault` subclass with a stable code — never a bare `ValueError`/`RuntimeError` — so the Fault Engine renders them consistently.


---

## Framework Docs: releases/1.3.2/mock_exports.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-mock_exports`

Mock Server & Collection Exports Specula features a schema-driven Mock Server and dynamic collection exporters to support rapid frontend integration and testing. --- Interactive Mock Server (`/specula/mock`) The mock server lets developers call any documented API endpoint and receive a plausible response payload without executing any business logic. Enabling the Mock Server The mock server is disabled by default. Enable it in your workspace configuration: How Payload Synthesis Works When a request is sent to `/specula/mock/<path>`, the mock router matches the path against the compiled API specification. It resolves the success response (`200`, `201`, or `202`) and inspects the JSON Schema: 1. **Explicit Examples**: If the schema or individual fields define an `example` or `examples` block, those values are returned directly. 2. **Plausible Synthesis**: If no examples are configured, Specula inspects the schema field types and synthesizes logical placeholders: * **Formatting Matchers**: String formats like `email`, `uuid`, `uri`, and `date-time` map to real formatted values (e.g. `user@example.com`, `550e8400-e29b-41d4-a716-446655440000`). * **Key Name Inference**: If a string field matches common keys (such as `email` or `url`), appropriate values are auto-injected. * **Standard Defaults**: Integers default to `42`, numbers to `3.14`, booleans to `True`, and arrays to single-item arrays. 3. **Recursion Safety**: Self-referencing models (e.g., a node containing a list of children of its own type) are automatically truncated when nesting depth exceeds `mock_max_depth` (default `4`). --- Exporters Specula exposes dynamic endpoints to download client collections configured with your current workspace routing topology and security schemes. 1. Postman Collection v2.1 * **Endpoint**: `/specula/export/postman` * **Output**: A compliant Postman v2.1 collection JSON file. * **Details**: * Groups endpoints into folders based on their tags or manifest module names. * Translates route variables like `/users/<id:int>` into Postman-compatible environment syntax: `/users/{{id}}`. * Pre-populates request bodies with JSON examples synthesized from Contract definitions. * Embeds default authorization headers mapped to the `{{access_token}}` environment variable. 2. Insomnia v4 Collection * **Endpoint**: `/specula/export/insomnia` * **Output**: A standard Insomnia v4 export file. * **Details**: * Includes workspace configuration mapping the current API. * Sets up base environment variables referencing `{{ _.base_url }}`. * Configures HTTP methods, headers, and body payloads automatically.

### Code Examples
```python
workspace.integrate(Integration.specula(
    title="Customer API",
    mock_server_enabled=True,
    mock_max_depth=4 # limit recursive definitions mapping
))

```



---

## Framework Docs: releases/1.3.2/security.md
**URL**: `https://tubox.cloud/docs/framework/releases-1.3.2-security`

Automated Security & Clearance Detection Specula integrates with Aquilia's security pipeline to automatically detect, map, and document authentication configurations. It translates pipeline guards and clearance levels into standard OpenAPI security requirements and rich custom metadata tags. --- Inferred Security Schemes The spec builder scans your controllers' and routes' pipeline nodes and handler decorators to identify authentication mechanisms. It automatically registers and configures security definitions in the OpenAPI `components.securitySchemes` catalog: | Inferred Guard Class Name | Generated Security Scheme | Schema Details | | :--- | :--- | :--- | | `AuthGuard` / `Auth` / `@authenticated` | `bearerAuth` | HTTP Bearer token (JWT) authentication. | | `ApiKeyGuard` / `ApiKey` | `apiKeyAuth` | `X-API-Key` request header authorization. | | `SessionGuard` / `Session` | `cookieAuth` | Session-based cookie verification (`session`). | | `BasicAuthGuard` / `Basic` | `basicAuth` | HTTP Basic authentication. | | `OAuth2Guard` / `OAuth2` | `oauth2` | OAuth2 Authorization Code flow. | --- Integrated Clearance Detection Specula integrates directly with the `aquilia.auth.clearance` system to identify role-based and attribute-based clearance levels. The builder resolves the merged clearance level from the controller boundary and individual route overrides: 1. **Public Routes**: If the effective clearance resolves to `AccessLevel.PUBLIC` (e.g. via `@grant(level=AccessLevel.PUBLIC)`), security requirements are omitted for that route. 2. **Protected Routes**: If the effective clearance is higher than public, `bearerAuth` is automatically registered as a requirement. --- Rich Metadata Extensions (`x-specula-security`) To support advanced observability and client generation, Specula embeds the full resolved authorization metadata in a custom vendor extension block (`x-specula-security`) inside each route's spec operation: This vendor block exposes: * **`authenticated`**: Boolean flag indicating if verification is required. * **`guards`**: Detailed list of active pipeline guard configurations, including roles, scopes, optional tags, resources, and evaluation settings. * **`clearance`**: The full clearance metadata, including `level` name, `level_value` integer, required `entitlements` lists, active `conditions` names, and matching resource `compartment` boundaries.

### Code Examples
```python
# Specula automatically registers bearerAuth with ["read", "write"] scopes
class OrderController(Controller):
    pipeline = [AuthGuard(), ScopeGuard("read", "write")]
    
    @GET("/")
    async def list_orders(self, ctx: RequestCtx): ...

```

```python
"x-specula-security": {
  "authenticated": true,
  "guards": [
    {
      "name": "RoleGuard",
      "type": "instance",
      "roles": ["admin", "compliance"],
      "require_all": false
    }
  ],
  "clearance": {
    "level": "INTERNAL",
    "level_value": 30,
    "entitlements": ["view_audit_logs", "override_fees"],
    "conditions": ["IsDuringOfficeHours", "IPRangeCondition"],
    "compartment": "finance"
  }
}

```



---

## Aquilia Skill Manual: aquilia-cache-storage-filesystem
**URL**: `https://tubox.cloud/docs/skills/aquilia-cache-storage-filesystem`

--- name: aquilia-cache-storage-filesystem description: "Build Aquilia cache, storage, and native filesystem workflows. Use for CacheService/backends/decorators, StorageConfig/backends/registry/effects, local/S3/GCS/Azure/SFTP/memory storage, and aquilia.filesystem async file operations/security." --- Aquilia Cache Storage Filesystem Purpose Use Aquilia's implemented cache, storage, and filesystem layers for data, blobs, and async file operations. Trigger Conditions Use for cache configuration, `@cached`, invalidation, memory/redis/composite cache, storage backends, file uploads/downloads, path traversal protection, async open/read/write/copy/move/delete, or storage effects. Inputs - Cache backend, TTL, namespace, key builder, serializer, and secret key if needed. - Storage backend config: local, memory, S3, GCS, Azure Blob, SFTP, or composite. - File paths, roots, streaming requirements, and security constraints. Execution Flow 1. Configure cache through `Integration.cache(...)` or cache-specific config; use `CacheService` and decorators for app code. 2. Configure storage through `Workspace.storage(...)` or `Integration.storage(...)`; create backends via storage registry. 3. Use `aquilia.filesystem` async helpers for local filesystem work with validation. 4. For user-controlled paths, validate/sanitize with filesystem and storage security helpers. 5. Test with memory/local backends before cloud backends. Constraints - Do not bypass path validation for user-controlled names. - Redis cache/socket backends require optional redis dependencies. - Cloud storage providers require credentials and optional SDKs; keep credentials out of generated code. Implementation Anchors `aquilia/cache/`, `aquilia/storage/`, `aquilia/filesystem/`, `aquilia/storage/backends/`, `aquilia/cache/backends/`, `tests/test_storage_system.py`, `tests/test_filesystem_comprehensive.py`, `examples/cache_http_edge_app/`, `examples/storage_filehub_app/`. Examples - Add `Integration.cache(backend="memory", default_ttl=300)`. - Configure local storage with root `var/uploads`. - Use `await write_file(path, data)` after validating relative paths. Failure Handling Cache serialization failures map to cache faults. Storage missing files use storage faults, not builtin exceptions. Path traversal and null byte attempts should be rejected before I/O.


---

## Aquilia Skill Manual: aquilia-http-versioning-client
**URL**: `https://tubox.cloud/docs/skills/aquilia-http-versioning-client`

--- name: aquilia-http-versioning-client description: "Build Aquilia outbound HTTP client and API versioning workflows. Use for aquilia.http client/session/request/response/auth/cookies/multipart/streaming/retry/interceptors/pool/middleware and versioning strategies, decorators, negotiation, middleware, resolvers, graph, and sunset behavior." --- Aquilia Http Versioning Client Purpose Implement outbound HTTP calls and versioned inbound APIs with the actual Aquilia HTTP and versioning subsystems. Trigger Conditions Use for HTTP client sessions, retries, interceptors, streaming, multipart, cookies/auth, API version decorators, URL/header/media-type negotiation, sunset headers, or route version debugging. Inputs - Base URL, method, headers, auth, retry policy, timeout, stream/multipart payload. - Versioning strategy, default version, supported versions, route version metadata, deprecation/sunset rules. Execution Flow 1. Use `aquilia.http` client/session/request/response primitives for outbound calls instead of ad hoc libraries when framework integration matters. 2. Configure versioning through `VersioningIntegration` or `Integration.versioning(...)`. 3. Decorate controllers/routes with version metadata or route decorator `version=` args. 4. Let `ASGIAdapter._resolve_route_inputs()` pre-resolve versioning before route matching. 5. Use version middleware/negotiation for request state and error responses. Constraints - Do not claim every versioning strategy exists without checking `strategy.py` and integration config. - Route version matching happens after path/method match; neutral routes remain matchable. - Preserve streaming semantics and avoid buffering large bodies unless required. Implementation Anchors `aquilia/http/`, `aquilia/versioning/`, `aquilia/integrations/versioning_cfg.py`, `aquilia/asgi.py`, `aquilia/controller/decorators.py`, `tests/test_http_client.py`, `tests/test_versioning.py`, `examples/versioned_public_api_app/`. Examples - Configure default version `1.0` with versions `["1.0", "2.0"]`. - Add `@GET("/items", version="2.0")` to a controller method. - Use HTTP retry/interceptor config for an external API client service. Failure Handling If a versioned route 404s, check stripped path and resolved version. If negotiation fails, inspect version parser/resolver errors. If outbound retries hide errors, log final failure with request metadata but not secrets.


---

## Aquilia Skill Manual: aquilia-workspace-bootstrap
**URL**: `https://tubox.cloud/docs/skills/aquilia-workspace-bootstrap`

--- name: aquilia-workspace-bootstrap description: "Create and adjust Aquilia workspaces using the real Workspace, Module, AquilaConfig, runtime, and aq init/add flows. Use for workspace.py, project bootstrap, env config, module pointers, and starter project structure." --- Aquilia Workspace Bootstrap Purpose Create or repair Aquilia `workspace.py` and starter project structure using the Python-native builder API. Trigger Conditions Use when the user asks to create a project, edit workspace runtime settings, add modules, configure integrations, set env config, or debug `aq init workspace` / `aq add module` output. Inputs - Workspace name, root path, runtime mode/host/port/reload. - Module names with route prefixes, imports, exports, and tags. - Required integrations: database, cache, sessions, auth, templates, storage, tasks, i18n, OpenAPI, admin, mail, MLOps, or provider settings. Execution Flow 1. Prefer `aq init workspace <name>` for new projects when CLI use is acceptable; otherwise mirror `WorkspaceGenerator` output. 2. Define `workspace.py` with `Workspace(...).runtime(...).module(Module(...).route_prefix(...)).integrate(...)`. 3. Keep component declarations out of `workspace.py`; `Module` is an orchestration pointer. 4. Use `AquilaConfig`, `Env`, and `Secret` for Python-native environment config. 5. Cross-check real examples such as `examples/multi_module_native_app/workspace.py`. Constraints - Do not recommend YAML as canonical config; `ConfigLoader` and `pyconfig.py` make Python-native config canonical. - Do not use deprecated `Module.register_*` methods for new code. - If auth is enabled, sessions are required by `AquiliaServer._setup_middleware()`. Implementation Anchors `aquilia/config_builders.py`, `aquilia/pyconfig.py`, `aquilia/config.py`, `aquilia/cli/generators/workspace.py`, `aquilia/cli/commands/init.py`, `examples/*/workspace.py`. Examples - "Create a workspace with accounts, catalog, orders, and realtime modules." - "Move controller declarations out of workspace.py into module manifests." - "Add memory cache, local storage, templates, and OpenAPI." Failure Handling If `workspace.py` is missing, runtime raises `FileNotFoundError`; create it or set `AQUILIA_WORKSPACE`. If route prefixes are wrong, remember `Module.route_prefix()` wins over manifest `route_prefix`. If discovery fails, inspect `modules/<name>/manifest.py` imports and sys.path.


---

## Aquilia Skill Manual: aquilia-artifacts-release-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-artifacts-release-builder`

--- name: aquilia-artifacts-release-builder description: "Build and manage Aquilia artifacts and release bundles. Use for Artifact, ArtifactBuilder, ArtifactReader, ArtifactStore, integrity/provenance, config/code/model/template/migration/registry/route/DI graph artifacts, signing, freeze, and aq artifact commands." --- Aquilia Artifacts Release Builder Purpose Create, inspect, verify, diff, bundle, and release Aquilia artifacts using the implemented artifact system. Trigger Conditions Use for artifact store operations, release bundles, provenance, integrity verification, frozen manifests, route/registry/DI graph artifacts, and `aq artifact` / `aq freeze` workflows. Inputs - Artifact kind, name, version, payload, tags, provenance, store directory, bundle path, signing requirement. - Whether operation should be read-only, destructive, or dry-run. Execution Flow 1. Use `ArtifactBuilder` to construct typed artifacts and include provenance/integrity metadata. 2. Persist through `FilesystemArtifactStore` or `MemoryArtifactStore`. 3. Inspect and verify with `ArtifactReader` and store APIs. 4. Use CLI `aq artifact list/inspect/verify/verify-all/gc/export/diff/history/import/count/stats` for operations. 5. Use `aq freeze` when generating reproducible release artifacts. Constraints - Do not bypass integrity checks when importing or deploying artifacts. - Garbage collection must respect keep lists and dry-run where available. - Unknown artifact kinds should be registered with `register_artifact_kind` before use. Implementation Anchors `aquilia/artifacts/`, `aquilia/cli/commands/artifacts.py`, `aquilia/cli/commands/freeze.py`, `aquilia/signing.py`, `examples/artifacts_release_app/`. Examples - Export a release bundle with selected artifact names. - Verify all artifacts in `artifacts/` before publishing. - Diff two versions of a config or migration artifact. Failure Handling Integrity mismatch should block import/deploy. Missing artifacts should produce clear name/version guidance. If Crous/frozen formats fail, fall back only where code supports JSON behavior.


---

## Aquilia Skill Manual: aquilia-security-hardening
**URL**: `https://tubox.cloud/docs/skills/aquilia-security-hardening`

--- name: aquilia-security-hardening description: "Apply Aquilia security hardening across auth, sessions, middleware, storage/filesystem, templates, cache signing, admin, ORM, provider credentials, CSRF/CORS/CSP/HSTS, rate limiting, path validation, and secret handling. Use when security-sensitive framework behavior is involved." --- Aquilia Security Hardening Purpose Make security-sensitive Aquilia changes using implemented hardening primitives instead of generic advice. Trigger Conditions Use for authentication secrets, password policy, token binding, CSRF/CORS/CSP/HSTS, sessions/cookies, admin access, path traversal, storage roots, template sandboxing, cache signing, SQL injection prevention, provider credentials, or production hardening. Inputs - Threat surface, environment, config values, affected subsystem, and acceptable compatibility tradeoffs. - Whether app is dev/test/prod and whether public clients need browser access. Execution Flow 1. Identify the subsystem: auth/session, middleware, template, storage/filesystem, ORM/database, cache, admin, provider, or deployment. 2. Use implemented hardening classes such as `CSRFProtection`, `SecurityHeaders`, `TokenBinder`, security middleware, storage/filesystem validators, template sandboxing, and password policy. 3. Keep secrets in `Secret`/env-backed config or provider credential stores. 4. Validate behavior with focused tests and existing security tests. 5. Document any deliberately relaxed dev settings separately from production settings. Constraints - Do not turn off CSRF/CORS/CSP/session cookie protections without stating the risk and scope. - Do not log raw secrets, tokens, passwords, provider credentials, or full PII identifiers. - Do not bypass ORM/query parameterization or path validators for user input. Implementation Anchors `aquilia/auth/hardening.py`, `aquilia/middleware_ext/security.py`, `aquilia/filesystem/_security.py`, `aquilia/storage/base.py`, `aquilia/templates/security.py`, `aquilia/signing.py`, `aquilia/providers/render/store.py`, `tests/test_*security*.py`, `SECURITY.md`. Examples - Require `Secret(env="AQ_SECRET_KEY", required=True)` in production config. - Add CSP and HSTS middleware for browser-facing apps. - Sanitize uploaded filenames before writing through storage/filesystem APIs. Failure Handling If hardening breaks a client, isolate which middleware/header/policy changed and adjust narrowly. If credentials are already leaked, rotate them; do not just redact code. If tests need relaxed security, scope the override to test settings only.


---

## Aquilia Skill Manual: aquilia-admin-dashboard-ops
**URL**: `https://tubox.cloud/docs/skills/aquilia-admin-dashboard-ops`

--- name: aquilia-admin-dashboard-ops description: "Build and operate Aquilia admin dashboard features. Use for AdminIntegration, AdminModules, admin templates/controllers/security/audit/users/permissions/monitoring/storage/tasks/provider pages, and aq admin commands." --- Aquilia Admin Dashboard Ops Purpose Configure and extend the built-in Aquilia admin dashboard and admin CLI operations. Trigger Conditions Use for admin dashboard setup, admin pages, users/staff/superuser management, audit logs, permissions, monitoring, storage/tasks/mail admin modules, and `aq admin` commands. Inputs - Admin site title, enabled modules, security settings, database URL, user credentials, and page/module requirements. - Whether operation is interactive or non-interactive. Execution Flow 1. Add `AdminIntegration(...)` to workspace and configure `AdminModules` for enabled areas. 2. Use admin CLI: `aq admin check`, `createsuperuser`, `createstaff`, `listusers`, `changepassword`, `setup`, `status`, and `audit`. 3. Extend templates/controllers using existing admin registry, permissions, hooks, widgets, and audit models. 4. Keep admin pages backed by implemented services and templates under `aquilia/admin/`. 5. Test admin behavior with admin tests and example admin app. Constraints - Admin authentication/authorization must use existing admin security and permissions paths. - Do not store plaintext passwords; use Aquilia password hashing paths. - Interactive commands have prompt validation; non-interactive mode must provide required values. Implementation Anchors `aquilia/admin/`, `aquilia/integrations/admin.py`, `aquilia/cli/__main__.py` admin section, `tests/test_admin*.py`, `examples/admin_dashboard_app/`. Examples - `.integrate(AdminIntegration(site_title="Commerce Admin", modules=AdminModules(audit=True, monitoring=True)))`. - Run `aq admin setup -y --database-url sqlite:///db.sqlite3`. - Add a custom admin view by following `admin/controller.py` and templates conventions. Failure Handling If admin pages are forbidden, inspect permissions and session/auth state. If setup fails, verify DB connectivity and migrations. If audit output is empty, confirm audit integration and table creation.


---

## Aquilia Skill Manual: aquilia-contract-validation
**URL**: `https://tubox.cloud/docs/skills/aquilia-contract-validation`

--- name: aquilia-contract-validation description: "Build Aquilia Contract validation, schema, projection, lens, facet, and request/response molding workflows. Use for Contract classes, facets, sealing/casting, OpenAPI schema generation, request_contract/response_contract, and model-world contracts." --- Aquilia Contract Validation Purpose Use Aquilia Contracts for request validation, response shaping, OpenAPI schemas, and model-world contracts. Trigger Conditions Use for data validation, typed request bodies, response projections, facets, lenses, annotations, schema generation, `request_contract`, `response_contract`, and Contract security issues. Inputs - Contract fields/facets, required/optional behavior, projection rules, request data, response object/data, and OpenAPI requirements. Execution Flow 1. Define `Contract` classes with facets from `aquilia.contracts`. 2. In controllers, pass Contract classes to route decorators or instantiate explicitly with request data. 3. Seal/cast input before handing data to services. 4. Use projections/lenses for response shaping when returning subsets or derived views. 5. Generate schemas through contract schema integration for OpenAPI. Constraints - Do not treat Contracts as ORM models; they are validation/projection contracts. - Validate and seal user input before service mutation. - Do not leak hidden/write-only fields in response projections. Implementation Anchors `aquilia/contracts/`, `aquilia/controller/decorators.py`, `aquilia/controller/engine.py`, `aquilia/patterns/openapi.py`, `tests/test_contract_*.py`, `examples/rest_api_contract/`, `examples/crud_app/modules/projects/contracts.py`. Examples - Use `ProjectCreateContract(data=await ctx.json())` then `await contract.is_sealed_async()`. - Add `request_contract=CreateUserContract` to `@POST`. - Return a projected response with read-only and hidden fields respected. Failure Handling Cast/seal/projection failures should map to contract faults. If schemas are wrong, inspect facet definitions and schema generator output. If sensitive fields leak, audit projection and facet annotations.


---

## Aquilia Skill Manual: aquilia-runtime-lifecycle-debugger
**URL**: `https://tubox.cloud/docs/skills/aquilia-runtime-lifecycle-debugger`

--- name: aquilia-runtime-lifecycle-debugger description: "Debug Aquilia runtime startup, discovery, bootstrap, ASGI lifespan, server startup/shutdown, health, route registration, and lifecycle hook behavior. Use for AquiliaRuntime, AquiliaServer, entrypoint, and production boot issues." --- Aquilia Runtime Lifecycle Debugger Purpose Diagnose runtime phase failures and lifecycle behavior from `AquiliaRuntime`, `AquiliaServer`, `ASGIAdapter`, and `LifecycleCoordinator`. Trigger Conditions Use for startup failures, missing `workspace.py`, missing manifests, route registration gaps, lifespan errors, health endpoint behavior, startup/shutdown hooks, and production entrypoint issues. Inputs - Workspace root and `AQUILIA_WORKSPACE`/`AQUILIA_ENV` values. - Error logs or phase where boot fails. - List of modules expected to load. Execution Flow 1. Trace phases: `CREATED -> CONFIGURING -> DISCOVERING -> BOOTSTRAPPING -> READY -> RUNNING`. 2. Confirm `workspace.py` exists and module names are discoverable by `AquiliaRuntime._extract_module_names()`. 3. Inspect imports of `modules.<name>.manifest` and dynamic discovery of `modules/*/manifest.py`. 4. Check `AquiliaServer` setup for Aquilary, RuntimeRegistry, DI, middleware, controller compiler/router, sockets, templates, auth/sessions, and health registry. 5. For request issues, trace `ASGIAdapter.handle_http()` route matching and middleware chain caching. Constraints - Do not bypass `AquiliaRuntime` with generated `runtime/app.py`; runtime.py is the consolidated bootstrap path. - Do not mutate env values silently; report `AQUILIA_WORKSPACE` and mode assumptions. - Lifespan startup/shutdown should go through server coordinator paths. Implementation Anchors `aquilia/runtime.py`, `aquilia/entrypoint.py`, `aquilia/server.py`, `aquilia/asgi.py`, `aquilia/lifecycle.py`, `aquilia/health.py`, `tests/test_runtime.py`. Examples - "Why does uvicorn aquilia.entrypoint:app return a 503?" - "My module manifest imports but routes do not show up." - "Debug a startup hook that rolls back app startup." Failure Handling `FileNotFoundError` means workspace path resolution failed. Import errors in `DISCOVERING` point to module manifest imports. Lifecycle failures transition to `ERROR` and trigger rollback; inspect the hook and dependency order.


---

## Aquilia Skill Manual: aquilia-auth-session-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-auth-session-builder`

--- name: aquilia-auth-session-builder description: "Build Aquilia authentication and session workflows. Use for AuthManager, tokens, password hashing/policy, guards, clearance, OAuth, MFA, session policies/stores/transports, auth middleware, and protected controllers." --- Aquilia Auth Session Builder Purpose Configure and implement Aquilia auth/session flows using the actual auth and session subsystems. Trigger Conditions Use for login/session identity, JWT/token config, password hashing, RBAC/ABAC, clearance decorators, route guards, OAuth2/PKCE, MFA, session stores/transports, or auth middleware behavior. Inputs - Auth settings: secret key, algorithm, issuer, audience, token TTLs, password policy. - Session policies: TTL, idle timeout, persistence, cookie/header transport, store. - Controller protection requirements: roles, scopes, permissions, clearance conditions. Execution Flow 1. Enable sessions with `Workspace.sessions(...)`; auth forces sessions on in server middleware setup. 2. Configure auth through `Integration.auth(...)`, `AuthConfig`, or workspace security settings as appropriate. 3. Use decorators/guards from `aquilia.auth.decorators`, `aquilia.auth.guards`, and clearance helpers for controller protection. 4. Use `AuthManager`, `TokenManager`, `PasswordHasher`, stores, and session bridge through DI where possible. 5. Test protected routes with `aquilia.testing.TestClient` bearer token or session cookie helpers. Constraints - Do not use insecure default secrets; `AuthConfig.secret_key` must be set explicitly for real auth. - Cookie security settings depend on environment; do not turn off httponly casually. - Clearance and auth decorators should return structured auth faults or challenge responses, not raw exceptions. Implementation Anchors `aquilia/auth/*.py`, `aquilia/auth/integration/*.py`, `aquilia/sessions/*.py`, `aquilia/middleware_ext/session_middleware.py`, `tests/test_auth_system.py`, `tests/test_sessions_system.py`, `examples/auth_app/`. Examples - Protect a route with `@authenticated` or `@requires(AdminGuard())`. - Add `DEFAULT_USER_POLICY` to workspace sessions. - Implement a clearance rule with `@grant(level=AccessLevel.WRITE, conditions=[is_owner_or_admin])`. Failure Handling If auth is enabled but sessions fail, inspect session engine creation first. Token errors should map to auth faults. Password validation failures come from `PasswordPolicy`; return user-safe messages only.


---

## Aquilia Skill Manual: aquilia-discovery-manifest-sync
**URL**: `https://tubox.cloud/docs/skills/aquilia-discovery-manifest-sync`

--- name: aquilia-discovery-manifest-sync description: "Use Aquilia discovery and manifest synchronization workflows. Use for auto-discovery, PackageScanner, DiscoveryInspector, analytics, aq discover --sync/--dry-run/--json, manifest update/check/freeze, workspace module config generation, and component sync issues." --- Aquilia Discovery Manifest Sync Purpose Discover controllers/services/models/tasks/sockets and synchronize manifests/workspace metadata safely. Trigger Conditions Use for missing auto-discovered components, `aq discover`, `aq analytics`, `aq manifest update`, workspace module config regeneration, discovery reports, or manifest drift checks. Inputs - Workspace path, module name, sync/check/freeze/dry-run/json mode. - Desired component patterns and whether auto-discovery is enabled. Execution Flow 1. Inspect `AppManifest.auto_discover` and `discover_patterns`. 2. Use `RuntimeRegistry.perform_autodiscovery()` behavior as the runtime reference. 3. For CLI discovery, use `DiscoveryInspector` and `aq discover --dry-run` before `--sync`. 4. For manifest updates, use `aq manifest update <module> --check` in CI and `--freeze` for strict mode where implemented. 5. Preserve the workspace/manifest split: workspace modules are pointers; module manifests own components. Constraints - Do not sync by regex alone when AST-based discovery is available. - Do not write discovery changes without dry-run/check when the user asked for audit only. - Avoid adding private modules or names beginning with `_`/`.`. Implementation Anchors `aquilia/discovery/engine.py`, `aquilia/utils/scanner.py`, `aquilia/aquilary/core.py`, `aquilia/cli/commands/discover.py`, `aquilia/cli/commands/analytics.py`, `aquilia/cli/commands/manifest.py`, `aquilia/cli/generators/workspace.py`. Examples - `aq discover --path . --dry-run --json`. - `aq discover --sync` to update detected components. - `aq manifest update orders --check` in CI. Failure Handling If discovery imports have side effects, use AST/static mode. If sync would produce invalid Python, generators should skip writes after syntax validation. If components are still missing, check package names and `__init__.py` availability.


---

## Aquilia Skill Manual: aquilia-task-worker-scheduler
**URL**: `https://tubox.cloud/docs/skills/aquilia-task-worker-scheduler`

--- name: aquilia-task-worker-scheduler description: "Build Aquilia background task workflows. Use for @task, TaskManager, TaskBackend, MemoryBackend, Worker, intervals, cron schedules, retries, queues, startup task registration, and task-related module manifests/CLI behavior." --- Aquilia Task Worker Scheduler Purpose Implement background jobs and periodic work using Aquilia's task registry, manager, scheduler, and workers. Trigger Conditions Use for async background jobs, queues, priorities, retries, scheduled tasks, module `tasks.py`, `BackgroundTaskConfig`, and testing task execution. Inputs - Task function name, queue, priority, retry count, timeout, and schedule. - Backend choice and worker count. - Module ownership and whether tasks should be auto-discovered. Execution Flow 1. Define task functions with `@task(...)` in a module `tasks.py` or explicit path. 2. Configure workspace tasks with `Workspace.tasks(...)` or `Integration.tasks(...)`. 3. Add module-level `BackgroundTaskConfig` when manifest visibility is needed. 4. Use `TaskManager` to enqueue and `Worker` to process jobs. 5. Use `every(...)` and `cron(...)` from task schedules for periodic work. Constraints - Aquilia tasks execute registered tasks only; do not add arbitrary function reference resolution. - Keep task payloads serializable and small enough for the backend. - Long-running tasks need explicit timeout/retry policy. Implementation Anchors `aquilia/tasks/decorators.py`, `aquilia/tasks/engine.py`, `aquilia/tasks/job.py`, `aquilia/tasks/schedule.py`, `aquilia/tasks/worker.py`, `aquilia/manifest.py`, `examples/background_jobs/`, `tests/test_tasks_system.py`. Examples - Add `@task(name="send_digest", queue="mail", retries=3)`. - Configure `.tasks(num_workers=4, backend="memory", scheduler_tick=15.0)`. - Add `background_tasks=BackgroundTaskConfig(tasks=["modules.jobs.tasks:cleanup"])`. Failure Handling Unknown task names should raise task resolution faults. Enqueue/backend failures map to task faults. Periodic schedule parse errors should be handled before worker startup.


---

## Aquilia Skill Manual: aquilia-di-service-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-di-service-builder`

--- name: aquilia-di-service-builder description: "Create and debug Aquilia dependency injection providers, services, factories, scopes, request scopes, lifecycle hooks, Inject annotations, and DI diagnostics. Use for service construction and provider resolution issues." --- Aquilia Di Service Builder Purpose Register and resolve Aquilia services consistently through the scoped DI container. Trigger Conditions Use when adding services, factories, provider bindings, constructor injection, request-scoped dependencies, lifecycle hooks, or debugging `ProviderNotFoundError`, scope warnings, or DI cycles. Inputs - Service classes/factories and constructor type hints. - Desired scope: `singleton`, `app`, `request`, `transient`, `pooled`, or `ephemeral`. - Optional `Annotated[..., inject(...)]` token/tag/optional metadata. Execution Flow 1. Add service import paths to `AppManifest.services` or rely on auto-discovery for classes ending in `Service` or decorated with `@service`. 2. Use `@service(scope="app")`, `@factory(...)`, `@provides(...)`, and `inject(...)` where explicit DI metadata is needed. 3. Let `AquiliaServer` call `RuntimeRegistry._register_services()` before controller factory creation. 4. Resolve dependencies with `await container.resolve_async(Type)` in async code. 5. Use request scopes from `Container.create_request_scope()` for per-request values. Constraints - Do not call sync `resolve()` from an async context; `Container` raises `DIResolutionFault`. - Avoid captive dependencies: request/ephemeral providers resolved into singleton/app containers produce warnings. - Manifest import paths are validated to block dangerous module imports. Implementation Anchors `aquilia/di/core.py`, `aquilia/di/providers.py`, `aquilia/di/decorators.py`, `aquilia/di/diagnostics.py`, `aquilia/aquilary/core.py`, `tests/test_di_system.py`. Examples - Register `modules.orders.services:OrdersService` and inject it into `OrdersController.__init__`. - Use `Annotated[Repository, inject(tag="readonly")]` for tagged dependencies. - Add `async_init`, `on_startup`, or `on_shutdown` to a service that owns resources. Failure Handling For missing providers, inspect `manifest.services`, auto-discovery, and type hints. For cycles, inspect `ResolveCtx.stack` or DI diagnostics. If a string annotation fails to resolve, prefer real imported types or controlled `get_type_hints` compatible annotations.


---

## Aquilia Skill Manual: aquilia-framework-audit
**URL**: `https://tubox.cloud/docs/skills/aquilia-framework-audit`

--- name: aquilia-framework-audit description: "Audit and navigate the Aquilia framework from actual source code. Use when a user asks to understand Aquilia architecture, execution flow, subsystem boundaries, code ownership, or to derive changes/skills/docs from implementation rather than assumptions." --- Aquilia Framework Audit Purpose Build an implementation-backed model of Aquilia before editing framework code, docs, examples, or skills. Trigger Conditions Use for Aquilia architecture audits, subsystem maps, runtime tracing, source-backed documentation, and any cross-cutting change that touches runtime, manifests, DI, CLI, integrations, or generated project structure. Inputs - Repository root containing `aquilia/`, `tests/`, `examples/`, `docs/modules/`, and `pyproject.toml`. - Optional subsystem or workflow name. - Optional output format: report, checklist, risk map, or implementation plan. Execution Flow 1. Start read-only. Inspect `pyproject.toml`, `README.md`, `GUIDE.md`, `aquilia/__init__.py`, `aquilia/runtime.py`, `aquilia/server.py`, `aquilia/asgi.py`, `aquilia/manifest.py`, `aquilia/config_builders.py`, and `aquilia/cli/__main__.py`. 2. Trace bootstrap: `workspace.py` -> `ConfigLoader` -> `AquiliaRuntime.configure/discover/bootstrap` -> `AquiliaServer` -> `Aquilary.from_manifests` -> `RuntimeRegistry` -> `ControllerRouter`/`ASGIAdapter`. 3. Inventory affected packages with `rg` before editing. Use examples and tests only to confirm source behavior. 4. Report findings with file anchors and separate implemented behavior from inferred intent. Constraints - Do not infer capabilities from package names, README claims, or docs alone. - Treat `workspace.py` as orchestration and module `manifest.py` as module internals. - Note deprecated surfaces such as `Module.register_controllers()` and `AppManifest.database` instead of recommending them. Implementation Anchors `aquilia/runtime.py`, `aquilia/server.py`, `aquilia/asgi.py`, `aquilia/aquilary/core.py`, `aquilia/manifest.py`, `aquilia/config_builders.py`, `aquilia/cli/__main__.py`, `examples/reference_suite/`. Examples - "Audit why a controller route is not registered in my Aquilia app." - "Map every subsystem touched by adding a new workspace integration." - "Create a source-backed architecture summary for Aquilia runtime startup." Failure Handling If source and docs disagree, trust source and flag docs as stale. If imports execute workspace code unexpectedly, switch to static inspection with `rg`, `sed`, and AST parsing. If generated and backup files coexist, identify the canonical runtime path before changing anything.


---

## Aquilia Skill Manual: aquilia-mlops-model-lifecycle
**URL**: `https://tubox.cloud/docs/skills/aquilia-mlops-model-lifecycle`

--- name: aquilia-mlops-model-lifecycle description: "Build Aquilia MLOps model packaging, registry, serving, rollout, observability, plugins, lineage, experiments, export, and admin workflows. Use for aquilia.mlops APIs and aq pack/model/mlops-deploy/observe/export/plugin/lineage/experiment commands." --- Aquilia Mlops Model Lifecycle Purpose Use Aquilia's implemented MLOps stack for model packaging, registry, runtime serving, deployment rollout, observability, plugins, lineage, and experiments. Trigger Conditions Use for modelpack archives, registry push/inspect/verify, serving models, ONNX/edge export, drift detection, metrics, rollout plans, plugin management, lineage queries, and A/B experiments. Inputs - Model path, name, version, framework/runtime, env lock, signing key, registry URL, rollout versions, drift data, plugin package, or experiment arms. Execution Flow 1. Use CLI groups from `mlops_cmds.py`: `pack`, `model`, `mlops-deploy`, `observe`, `export`, `plugin`, `lineage`, and `experiment`. 2. Use `MLOpsManifest`, runtime/base classes, registry service/storage, orchestrator, scheduler, and observe modules where programmatic integration is needed. 3. Configure workspace with `Integration.mlops(...)` or `Workspace.mlops(...)` when app-level MLOps is required. 4. Use contract APIs for request/response schemas when exposing MLOps endpoints. 5. Verify archives and signatures before deployment or registry push. Constraints - Optional dependencies are split by extras: core mlops, onnx, torch, s3, bento, explain. - Do not fake support for a runtime if `select_runtime` or exporter code does not implement it. - Signing and registry credentials must not be committed. Implementation Anchors `aquilia/mlops/`, `aquilia/cli/commands/mlops_cmds.py`, `aquilia/integrations/mlops.py`, `aquilia/admin/templates/mlops.html`, `tests/test_mlops_*.py`, `examples/mlops_model_registry_app/`. Examples - `aq pack save model.pkl --name recommender --version 1.0.0 --framework sklearn`. - `aq model serve modelpack.aq --runtime python --port 9000`. - `aq mlops-deploy rollout fraud --from-version 1.0 --to-version 1.1 --strategy canary`. Failure Handling Pack integrity/signature failures should stop deployment. Missing optional ML dependencies should produce actionable install guidance. Drift/metrics failures should map to MLOps observe faults.


---

## Aquilia Skill Manual: aquilia-websocket-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-websocket-builder`

--- name: aquilia-websocket-builder description: "Build Aquilia WebSocket and realtime features. Use for SocketController, @Socket, OnConnect/OnDisconnect/Event/AckEvent/Subscribe/Unsubscribe/Guard decorators, adapters, envelopes, middleware, client generation, and aq ws commands." --- Aquilia Websocket Builder Purpose Implement realtime channels with Aquilia socket controllers and runtime adapters. Trigger Conditions Use for WebSocket endpoints, rooms, events, acknowledgements, subscriptions, presence, Redis/in-memory adapters, message validation, rate limits, and `aq ws` commands. Inputs - Socket path, namespace, allowed origins, message limits, event names, schemas, rooms, and adapter choice. - Whether generated TypeScript client output is needed. Execution Flow 1. Create a class decorated with `@Socket("/ws/path/:param", ...)` that subclasses `SocketController`. 2. Implement lifecycle methods with `@OnConnect()` and `@OnDisconnect()`. 3. Implement events with `@Event`, `@AckEvent`, `@Subscribe`, and `@Unsubscribe`; validate payloads with `Schema`. 4. Register the socket controller in `AppManifest.socket_controllers` or rely on socket auto-discovery. 5. Use `aq ws inspect`, `broadcast`, `gen-client`, `purge-room`, and `kick` for operational workflows. Constraints - Do not invent a Socket.IO protocol; use Aquilia envelopes/runtime classes. - Respect `allowed_origins`, `message_rate_limit`, and `max_message_size`. - Redis adapter requires redis optional dependency and URL configuration. Implementation Anchors `aquilia/sockets/decorators.py`, `aquilia/sockets/runtime.py`, `aquilia/sockets/connection.py`, `aquilia/sockets/envelope.py`, `aquilia/sockets/adapters/`, `aquilia/cli/commands/ws.py`, `examples/websocket_app/modules/chat/sockets.py`. Examples - Create `@Socket("/ws/chat/:room", allowed_origins=["*"], message_rate_limit=20)`. - Add `@Event("message.send", schema=Schema({"room": str, "text": str}), ack=True)`. - Generate a TypeScript client with `aq ws gen-client --out client.ts`. Failure Handling Handshake/auth/origin failures should map to socket faults. Invalid payloads should fail schema validation. If events do not register, inspect `socket_controllers` and `SocketCompiler` metadata.


---

## Aquilia Skill Manual: aquilia-fault-middleware-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-fault-middleware-builder`

--- name: aquilia-fault-middleware-builder description: "Build and debug Aquilia structured faults and middleware. Use for Fault subclasses, FaultDomain, FaultEngine, default handlers, Exception/Fault middleware, request IDs, CORS/CSP/CSRF/rate-limit/static middleware, and middleware chain ordering." --- Aquilia Fault Middleware Builder Purpose Represent errors as Aquilia faults and wire middleware in the order the server actually uses. Trigger Conditions Use for custom fault classes, error responses, middleware stack changes, request IDs, debug pages, security middleware, static middleware, rate limiting, or exception-to-response behavior. Inputs - Fault domain/code/message/severity/public metadata. - Middleware callable/class, scope, priority, and config. - Expected JSON or HTML response behavior. Execution Flow 1. Define faults by subclassing `Fault` or using domain-specific fault modules. 2. Set stable `code`, `message`, `domain`, and safe `public` exposure. 3. Register fault behavior through `FaultHandlingConfig` or server fault engine paths. 4. Add middleware with `MiddlewareStack.add(middleware, scope="global", priority=...)` or config-driven `middleware_chain`. 5. For security middleware, use implemented middleware in `aquilia/middleware_ext/` rather than inventing wrappers. Constraints - Faults require code, message, and domain; missing values raise `TypeError`. - Middleware order is scope rank then priority, wrapped in reverse when building handlers. - Internal `FaultMiddleware` and request scope middleware are framework plumbing and should remain present. Implementation Anchors `aquilia/faults/core.py`, `aquilia/faults/engine.py`, `aquilia/faults/domains.py`, `aquilia/middleware.py`, `aquilia/middleware_ext/*.py`, `aquilia/server.py`. Examples - Add a module fault domain with `FaultHandlingConfig(default_domain="ORDERS")`. - Configure CORS, CSP, HSTS, CSRF, rate limit, and static middleware using implemented middleware classes. - Return debug HTML for browser `Accept: text/html` in development. Failure Handling If clients see raw exceptions, verify `FaultMiddleware` and `ExceptionMiddleware` order. If sensitive metadata leaks, set `public=False` and sanitize metadata. If middleware does not run, inspect scope, priority, and `middleware_chain` config.


---

## Aquilia Skill Manual: aquilia-module-manifest-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-module-manifest-builder`

--- name: aquilia-module-manifest-builder description: "Create, update, debug, and sync Aquilia module manifests. Use when working with module manifest.py files, AppManifest, services/controllers/models/tasks/socket_controllers, imports/exports, auto_discovery, or aq add module." --- Aquilia Module Manifest Builder Purpose Create module-level configuration that matches Aquilia Manifest-First architecture. Trigger Conditions Use for module creation, `AppManifest` setup, imports/exports, component registration, auto-discovery, `aq add module`, `aq manifest update`, or `aq discover --sync`. Inputs - Module name, route prefix, fault domain, imports/exports. - Component import paths for controllers, services, models, middleware, guards, pipes, interceptors, tasks, and socket controllers. - Whether the module should be minimal, full, explicit, or auto-discovered. Execution Flow 1. Use `aq add module` when scaffolding; it mirrors `ModuleGenerator`. 2. In `manifest.py`, instantiate `AppManifest(name=..., version=..., controllers=[...], services=[...], base_path=...)`. 3. Add `models`, `socket_controllers`, `middleware`, `guards`, `pipes`, `interceptors`, `background_tasks`, `templates`, `faults`, `imports`, and `exports` only when needed. 4. Keep route prefix in `workspace.py` via `Module.route_prefix()`. 5. Run `aq validate` or inspect manifest import errors after changes. Constraints - Component refs must use `module.path:ClassName` where required. - Manifest `name` must be alphanumeric/underscore and `version` must be present. - Manifest-level `DatabaseConfig` is deprecated and ignored at runtime. Implementation Anchors `aquilia/manifest.py`, `aquilia/cli/generators/module.py`, `aquilia/cli/commands/add.py`, `aquilia/aquilary/core.py`, `aquilia/discovery/engine.py`, `examples/*/modules/*/manifest.py`. Examples - Add `socket_controllers=["modules.chat.sockets:ChatSocket"]`. - Export `OrdersService` so importing modules can use it. - Disable `auto_discover` for explicit production manifests. Failure Handling `ManifestValidationFault` points to structural issues. Missing components usually mean bad import paths or disabled discovery. Dependency cycles are found by the Aquilary dependency graph; inspect `imports` and `depends_on`.


---

## Aquilia Skill Manual: aquilia-deploy-provider-render
**URL**: `https://tubox.cloud/docs/skills/aquilia-deploy-provider-render`

--- name: aquilia-deploy-provider-render description: "Generate and operate Aquilia deployment/provider workflows. Use for aq deploy dockerfile/compose/kubernetes/nginx/ci/monitoring/env/all/makefile/render, deployment generators, Render provider login/status/env vars/deploy/destroy/status, and provider credential store." --- Aquilia Deploy Provider Render Purpose Use Aquilia's deployment generators and Render provider integration without inventing deployment behavior. Trigger Conditions Use for Dockerfile, docker-compose, Kubernetes, Nginx, CI, monitoring, env files, Makefile generation, Render deployments, provider auth, or Render environment variable management. Inputs - Workspace root, output directory, force/dry-run flags, monitoring/CI provider choice, image/region/plan/service name, Render token, env var names/values. Execution Flow 1. For generated deployment assets, use `aq deploy` subcommands and generator code in `deploy_gen.py`. 2. Prefer `--dry-run` before writing deployment files when available. 3. For Render auth, use `aq provider login render` and credential store paths. 4. For Render deploys, use `aq deploy render` flags for service, plan, region, instances, status, or destroy. 5. Manage Render env vars with `aq provider render env list/set/delete`. Constraints - Do not expose Render tokens; credential store encrypts and audits provider credentials. - Do not run destructive provider actions such as destroy without explicit user approval. - Generated deployment files should reflect workspace introspection rather than static assumptions. Implementation Anchors `aquilia/cli/commands/deploy_gen.py`, `aquilia/cli/generators/deployment.py`, `aquilia/cli/commands/provider.py`, `aquilia/providers/render/`, `examples/provider_render_deploy_app/`, `tests/test_render_provider.py`. Examples - `aq deploy dockerfile --dev --output . --dry-run`. - `aq deploy all --ci-provider github --monitoring`. - `aq provider render env set DJANGO_SECRET --service my-service`. Failure Handling If Docker/Kubernetes/Render tools are missing, surface the missing command. If provider credentials are absent, direct the user to provider login. For dry-run, never write files or call remote mutating APIs.


---

## Aquilia Skill Manual: aquilia-controller-api-builder
**URL**: `https://tubox.cloud/docs/skills/aquilia-controller-api-builder`

--- name: aquilia-controller-api-builder description: "Build Aquilia HTTP APIs with Controller, RequestCtx, Response, route decorators, contracts, filters, pagination, renderers, OpenAPI metadata, and route debugging. Use for controller methods and request/response behavior." --- Aquilia Controller Api Builder Purpose Implement Aquilia-native HTTP controllers that compile into `ControllerRouter` routes and execute through `ControllerEngine`. Trigger Conditions Use for API endpoints, CRUD controllers, request parsing, response formatting, route decorators, OpenAPI metadata, filters, pagination, content negotiation, or controller route debugging. Inputs - Controller class name, prefix, tags, HTTP methods, paths, and path parameter types. - Request body and response shape. - Optional request/response contracts, filters, search, ordering, pagination, renderers, throttles, timeouts, and version binding. Execution Flow 1. Subclass `Controller` and set `prefix` and `tags` when useful. 2. Use `@GET`, `@POST`, `@PUT`, `@PATCH`, `@DELETE`, `@HEAD`, `@OPTIONS`, or `@TRACE` with paths such as `/`, `/<key:str>`, or `/<id:int>`. 3. Accept `ctx: RequestCtx` for query/body/header/session/auth access. 4. Return `Response.json(...)` or a value convertible by `ControllerEngine._to_response()`. 5. Inject services through `__init__` type hints when they are registered in `AppManifest.services` or auto-discovered. Constraints - Do not manually register routes in `workspace.py`. - Keep handlers async unless there is a deliberate compatibility reason. - `ASGIAdapter` handles HEAD fallback to GET when a GET route exists. Implementation Anchors `aquilia/controller/decorators.py`, `aquilia/controller/base.py`, `aquilia/controller/compiler.py`, `aquilia/controller/router.py`, `aquilia/controller/engine.py`, `aquilia/response.py`, `examples/crud_app/modules/projects/controllers.py`. Examples - Implement `GET /projects/<key:str>` returning `Response.json(await service.get_project(key))`. - Add `@POST("/", status_code=201)` and validate `await ctx.json()` with a Contract. - Bind a route with `version="2.0"` for version-aware matching. Failure Handling A 404 means no route matched method/path/version. A 405 means path matched but method did not. DI errors usually come from unregistered constructor type hints. Use `aq inspect routes` and controller compiler metadata when available.


---

## Aquilia Skill Manual: aquilia-testing-debug-toolkit
**URL**: `https://tubox.cloud/docs/skills/aquilia-testing-debug-toolkit`

--- name: aquilia-testing-debug-toolkit description: "Use Aquilia testing and debugging utilities. Use for TestServer, TestClient, WebSocketTestClient, AquiliaTestCase, fixtures, mocks, aq test, debug pages, diagnostics, health, and framework regression tests." --- Aquilia Testing Debug Toolkit Purpose Test Aquilia apps in-process and debug framework behavior with real testing utilities. Trigger Conditions Use for writing tests, running `aq test`, in-process HTTP/WebSocket tests, fixtures, mock DI/cache/effects/fault/mail, debug pages, health checks, and regression coverage. Inputs - Manifests, config overrides, enabled subsystems, request paths, expected responses. - Pytest/unittest preference. - Optional live server requirement. Execution Flow 1. For in-process API tests, use `TestServer` and `TestClient`; no network socket is needed. 2. For unittest-style tests, subclass `AquiliaTestCase`; set `manifests`, `settings`, and subsystem enable flags. 3. For pytest, import fixtures from `aquilia.testing.fixtures`. 4. Use `TestResponse` helpers for JSON, headers, status, redirects, and cookies. 5. Run `aq test` or `python -m pytest tests/` depending on scope. Constraints - Prefer in-process tests unless real TCP behavior is required. - Enable subsystems explicitly in test cases to avoid hidden dependencies. - Keep workspace mutation out of tests unless testing generators/discovery. Implementation Anchors `aquilia/testing/`, `aquilia/debug/pages.py`, `aquilia/cli/commands/test.py`, `tests/`, `examples/*/tests/`. Examples - `async with TestServer(manifests=[manifest]) as srv: resp = await TestClient(srv).get("/")`. - Subclass `AquiliaTestCase` with `enable_sessions=True`. - Use `mail_outbox`, `di_container`, or `effect_registry` fixtures. Failure Handling If server exceptions should be captured rather than raised, configure `TestClient(raise_server_exceptions=False)`. If async fixtures fail, confirm pytest-asyncio is installed and `asyncio_mode=auto` from pyproject is active.


---

## Aquilia Skill Manual: aquilia-database-orm-migrations
**URL**: `https://tubox.cloud/docs/skills/aquilia-database-orm-migrations`

--- name: aquilia-database-orm-migrations description: "Build Aquilia database, sqlite, ORM model, query, transaction, and migration workflows. Use for DatabaseIntegration, typed DB configs, AquiliaDatabase, native sqlite, Model fields/managers, makemigrations/migrate/sqlmigrate/inspectdb/status, and schema snapshots." --- Aquilia Database Orm Migrations Purpose Implement and debug Aquilia database and model workflows from typed config through migrations. Trigger Conditions Use for `Workspace.database`, `Integration.database`, `SqliteConfig`/`PostgresConfig`/`MysqlConfig`/`OracleConfig`, `AquiliaDatabase`, native sqlite, `Model` subclasses, fields, querysets, transactions, and `aq db` commands. Inputs - Database URL or typed config. - Model classes and fields. - Migration directory, app filter, database alias, and whether to emit DSL or SQL. Execution Flow 1. Configure DB globally through `Workspace.database(...)` or `Integration.database(config=...)`. 2. Define models as Python `Model` subclasses with fields from `aquilia.models`. 3. Use async query APIs such as `Model.objects.filter(...).all()`, `Model.create(...)`, and transaction helpers. 4. Generate migrations with `aq db makemigrations`; apply with `aq db migrate`; inspect with `showmigrations`, `sqlmigrate`, `status`, or `inspectdb`. 5. For sqlite internals, use native `aquilia.sqlite` rather than deprecated aiosqlite paths. Constraints - Use parameterized query APIs; do not construct SQL with untrusted field/table names. - Manifest-level database config is deprecated and ignored at runtime. - Migration snapshots use Crous binary where available; do not hand-edit unless necessary. Implementation Anchors `aquilia/db/configs.py`, `aquilia/db/engine.py`, `aquilia/sqlite/`, `aquilia/models/base.py`, `aquilia/models/fields_module.py`, `aquilia/models/migration_gen.py`, `aquilia/cli/commands/model_cmds.py`, `examples/sqlite_inventory_app/`. Examples - Add `SqliteConfig(path="runtime/app.db", auto_create=True)` to a workspace. - Create `class Project(Model): key = CharField(max_length=64, unique=True)`. - Run `aq db makemigrations --app inventory` then `aq db migrate --plan`. Failure Handling Unsupported URLs raise database connection faults. Field validation raises `FieldValidationFault`. If startup guard complains about migrations, generate/apply migrations or set an explicit development auto-migration policy.


---

## Aquilia Skill Manual: aquilia-cli-workflow-operator
**URL**: `https://tubox.cloud/docs/skills/aquilia-cli-workflow-operator`

--- name: aquilia-cli-workflow-operator description: "Operate and extend the Aquilia aq CLI. Use for aq init/add/generate/validate/compile/run/serve/freeze/manifest/inspect/discover/analytics/mail/cache/i18n/db/ws/admin/provider/deploy/test commands and Click flag behavior." --- Aquilia Cli Workflow Operator Purpose Use and modify Aquilia CLI workflows according to the actual Click command tree. Trigger Conditions Use when the user asks about `aq` commands, CLI flags, project scaffolding, validation, inspection, run/serve, database migrations, WebSocket operations, provider/render auth, deployment generation, admin operations, or tests. Inputs - Command or workflow goal. - Workspace path and whether command may write files. - Desired flags such as `--yes`, `--minimal`, `--json`, `--dry-run`, `--check`, `--sync`, or provider-specific values. Execution Flow 1. Inspect `aquilia/cli/__main__.py` for command registration and global flags. 2. For implementation, follow delegated command modules in `aquilia/cli/commands/` and generators in `aquilia/cli/generators/`. 3. Use dry-run/check/json flags when present for inspection before writes. 4. Keep interactive behavior compatible with `sys.stdin.isatty()` and `--yes`/non-interactive paths. 5. Validate generated code with `aq validate`, `aq inspect`, or relevant test commands. Constraints - Operational commands require `workspace.py` through `_require_workspace()` except bootstrap-safe commands. - Name validation rejects uppercase starts and non lowercase/digit/hyphen/underscore characters. - Do not add undocumented flags without wiring them through command implementation and help text. Implementation Anchors `aquilia/cli/__main__.py`, `aquilia/cli/commands/*.py`, `aquilia/cli/generators/*.py`, `aquilia/cli/utils/prompts.py`, `tests/test_cli_model_shell_line_editing.py`. Examples - `aq init workspace my-api --minimal -y` - `aq add module orders --depends-on=accounts --route-prefix=/orders` - `aq db makemigrations --app inventory --format json` Failure Handling If a command fails outside a workspace, check `_require_workspace`. If generated files are stale, use manifest/discovery commands. If a command shells out, preserve dry-run behavior and surface missing external binaries clearly.


---

## Aquilia Skill Manual: aquilia-template-mail-i18n
**URL**: `https://tubox.cloud/docs/skills/aquilia-template-mail-i18n`

--- name: aquilia-template-mail-i18n description: "Build Aquilia templates, mail, and i18n workflows. Use for sandboxed Jinja templates, template loaders/context/bytecode cache/security, mail providers/messages/envelopes, i18n catalogs/locales/plurals/extraction/compile, and related CLI commands." --- Aquilia Template Mail I18n Purpose Implement UI/content delivery workflows that combine templates, mail, and localization using Aquilia subsystems. Trigger Conditions Use for `Integration.templates`, `TemplatesIntegration`, Jinja rendering, template security, static tags, mail providers, test emails, localized content, i18n extraction, and catalog compilation. Inputs - Template search paths, cache mode, sandbox flag, context processors. - Mail provider config: console, file, SMTP, SES, or SendGrid. - Locales, translation directories, source dirs, output catalog path, plural behavior. Execution Flow 1. Configure templates globally with `TemplatesIntegration` or `Integration.templates.*` and module templates with `TemplateConfig`. 2. Use `TemplateManager`/engine integration through DI or controller helpers where available. 3. Build mail with `MailIntegration`, provider objects, `MailAuth`, messages, envelopes, and `MailService`. 4. Configure i18n through `Workspace.i18n(...)` or `Integration.i18n(...)`; use CLI `aq i18n init/check/inspect/extract/coverage/compile`. 5. Test with console/file mail providers and in-memory template/cache settings before external providers. Constraints - Keep templates sandboxed unless there is a verified reason not to. - Do not put provider secrets in source; use env-backed auth fields. - i18n extraction should merge by default unless the user explicitly wants overwrite behavior. Implementation Anchors `aquilia/templates/`, `aquilia/mail/`, `aquilia/i18n/`, `aquilia/cli/commands/mail.py`, `aquilia/cli/commands/i18n.py`, `examples/templates_portal_app/`, `examples/mail_notifications_app/`, `examples/i18n_content_app/`. Examples - Add `TemplatesIntegration(search_paths=["templates"], cache="memory", sandbox=True)`. - Send a notification through a console mail provider in development. - Run `aq i18n extract --source-dirs modules,controllers --output locales/en/messages.json`. Failure Handling Template faults should include template path/context without leaking secrets. Mail provider failures should preserve envelope status. Missing locale keys should be surfaced by i18n check/coverage before runtime.


---

## Aquilia Skill Manual: aquilia-config-integration-manager
**URL**: `https://tubox.cloud/docs/skills/aquilia-config-integration-manager`

--- name: aquilia-config-integration-manager description: "Manage Aquilia Python-native configuration and typed integrations. Use for Integration.* builders, aquilia.integrations dataclasses, database/cache/storage/tasks/mail/templates/admin/openapi/security/session config, Env, Secret, and ConfigLoader behavior." --- Aquilia Config Integration Manager Purpose Configure Aquilia apps with the implemented builder and integration objects instead of ad hoc dictionaries. Trigger Conditions Use when changing `workspace.py` integrations, env config, typed database config, security/telemetry settings, or integration dataclasses under `aquilia/integrations/`. Inputs - Target integration type and values. - Environment names and required secrets. - Whether config should be global workspace config or module-level manifest config. Execution Flow 1. Prefer typed integration classes from `aquilia.integrations` or `Integration.*` builder methods from `config_builders.py`. 2. Use `Workspace.integrate(...)` for integration objects and `Workspace.database/tasks/storage/security/telemetry/sessions/i18n` for common convenience flows. 3. Use `AquilaConfig`, `Env`, and `Secret` for environment variants and secret resolution. 4. Confirm `to_dict()` output matches what `ConfigLoader` and `AquiliaServer` consume. 5. Keep module-specific component settings in `AppManifest` and global operational settings in `Workspace`. Constraints - Do not leak `Secret.reveal()` output into logs or generated docs. - Do not configure database through `AppManifest.database` for new code. - Validate whether an integration returns a dict or an `IntegrationConfig` object; `Workspace.integrate()` handles both. Implementation Anchors `aquilia/config_builders.py`, `aquilia/pyconfig.py`, `aquilia/config.py`, `aquilia/integrations/*.py`, `tests/test_integration_configs.py`, `tests/test_integration_wiring.py`. Examples - Add `Integration.database(config=PostgresConfig(...))`. - Add `MailIntegration(default_from=..., providers=[ConsoleProvider(...)])`. - Define `ProdEnv(BaseEnv)` with `Secret(env="AQ_SECRET_KEY", required=True)`. Failure Handling If config is missing, check `ConfigLoader.load()` merge order and env prefix. If a secret is required and absent, expect `ConfigMissingFault`. If a subsystem ignores config, trace its `get_*_config()` method or server setup path.
