Skip to main content

Async-native Python web framework with flow-first routing

Project description

Aquilia Logo

Aquilia

The async-native, manifest-first Python web framework.

Version License Python Tests


Aquilia is an async-native, manifest-first Python web framework that auto-discovers modules, wires dependency injection, and generates infrastructure manifests — no routing glue code, no manual Dockerfiles.

Features

  • Manifest-First Architecture — Modules declare controllers, services, and middleware in manifest.py. Aquilia discovers and wires them automatically.
  • Auto-DiscoveryPackageScanner traverses your workspace, finds modules, and registers them without boilerplate.
  • Scoped Dependency Injection — Hierarchical DI (singleton, app, request scopes) with annotation-driven providers.
  • Structured Fault System — Every error is a typed Fault subclass with domain, severity, code, and recovery strategy. No raw exceptions.
  • Clearance System — Declarative, multi-dimensional access control with access levels, entitlements, conditions, and tenant compartments.
  • API Versioning with Sunset — Epoch-based versioning with channel promotion, multi-strategy resolution (URL, header, query, media type), and RFC 8594 sunset enforcement.
  • SSE Streaming — First-class Server-Sent Events with SSEResponse and SSEEvent for real-time data and LLM token streaming.
  • OpenTelemetry — Built-in distributed tracing via OTelConfig and ASGI instrumentation middleware.
  • Production Security — HMAC-verified caches, path traversal protection, CSRF/CORS/CSP/HSTS guards, sandboxed Jinja2 templates.

Installation

pip install aquilia

jinja2 (templates) and aiosqlite (SQLite) are bundled in core — no extras needed to get started.

Extra What it adds
aquilia Core framework — controllers, DI, ORM, templates, filesystem, SQLite
aquilia[auth] Argon2 hashing, JWT, OAuth, cryptography
aquilia[postgres] asyncpg driver for PostgreSQL
aquilia[redis] Redis cache & WebSocket backends
aquilia[otel] OpenTelemetry API, SDK, OTLP exporter, ASGI instrumentation
aquilia[mail] SMTP email provider
aquilia[server] Gunicorn + Uvicorn workers for production
aquilia[full] Everything above — auth, postgres, redis, otel, mail, server, multipart

Quick Start

Aquilia is workspace-first — scaffold projects through the aq CLI.

1 — Create a workspace

aq init workspace my-app
cd my-app

This generates workspace.py, config/, and a starter page serving GET / immediately.

2 — Add a module

aq add module users

Generates modules/users/ with manifest.py, controllers.py, services.py, and models.py.

3 — Write a controller

# modules/users/controllers.py
from aquilia import Controller, GET, POST, RequestCtx, Response
from aquilia.controller.validation import validate_body

class UsersController(Controller):
    prefix = "/users"
    tags  = ["users"]

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

    @POST("/")
    @validate_body(CreateUserBlueprint)
    async def create_user(self, ctx: RequestCtx, body: dict):
        return Response.json({"created": body}, status=201)

No manual route registration — controllers in a module's manifest.py are discovered and wired automatically.

4 — Run the development server

aq serve

Serves on http://127.0.0.1:8000 with hot reload.

CLI

Command Description
aq init workspace <name> Scaffold a new workspace
aq add module <name> Add a module with manifest, controller, services, models
aq serve Start development server with hot reload
aq compile Compile manifests into a frozen artifact
aq validate Validate manifests, routes, and DI graph
aq inspect Inspect compiled routes, DI providers, and version graph

Code Examples

Structured Faults

from aquilia.faults import Fault, FaultDomain, Severity

class PaymentRequiredFault(Fault):
    def __init__(self, plan: str):
        super().__init__(
            code="PAYMENT_REQUIRED",
            message=f"Upgrade to {plan} to access this feature",
            domain=FaultDomain.SECURITY,
            severity=Severity.WARN,
            retryable=False,
            public=True,
        )

raise PaymentRequiredFault(plan="pro")

Or use built-in HTTP faults:

from aquilia.faults import NotFoundFault, ForbiddenFault

raise NotFoundFault(detail="/api/users/999 does not exist")
raise ForbiddenFault(detail="Insufficient permissions")

Clearance System — Declarative Access Control

from aquilia import Controller, GET, POST, DELETE, RequestCtx
from aquilia.auth.clearance import Clearance, AccessLevel, grant, exempt, is_verified, is_owner_or_admin

class DocumentController(Controller):
    prefix = "/documents"
    clearance = Clearance(level=AccessLevel.AUTHENTICATED)

    @GET("/")
    @grant(level=AccessLevel.PUBLIC)
    async def list_public(self, ctx: RequestCtx):
        return {"docs": []}

    @POST("/")
    @grant(entitlements=["documents:write"], conditions=[is_verified])
    async def create(self, ctx: RequestCtx):
        ...

    @DELETE("/{doc_id}")
    @grant(level=AccessLevel.CONFIDENTIAL, conditions=[is_owner_or_admin])
    async def delete(self, ctx: RequestCtx, doc_id: str):
        ...

SSE Streaming

import asyncio
from aquilia import Controller, GET, RequestCtx
from aquilia.sse import SSEEvent, SSEResponse

class StreamController(Controller):
    prefix = "/stream"

    @GET("/events")
    async def live_events(self, ctx: RequestCtx):
        return SSEResponse(self._generate())

    async def _generate(self):
        for i in range(100):
            yield SSEEvent(data=f"event {i}", event="update", id=str(i))
            await asyncio.sleep(0.5)

API Versioning with Sunset

from aquilia import Controller, GET
from aquilia.versioning import version, SunsetPolicy, VERSION_NEUTRAL

class UsersV2Controller(Controller):
    prefix = "/users"
    version = "2.0"

    @GET("/")
    async def list_v2(self, ctx):
        ...

class UsersV1Controller(Controller):
    prefix = "/users"
    version = "1.0"
    sunset = SunsetPolicy(grace_period="180d", warn_header=True)

    @GET("/")
    async def list_v1(self, ctx):
        ...

Architecture

The boot sequence: Manifests → Aquilary → RuntimeRegistry → Controllers → ASGI

Subsystem Purpose
Aquilary Core manifest registry, metadata, runtime wiring
Controller Route decorators (@GET, @POST), OpenAPI generation, filtering, pagination
DI Hierarchical dependency injection with singleton/app/request scopes
Faults Structured error system with 14+ domains, typed HTTP faults
Auth JWT/session auth, MFA, OAuth, RBAC/ABAC, clearance guards
Flow Typed routing and composable request pipelines with effect scopes
Models/ORM Async ORM with query builder, migrations, transactions
Templates Sandboxed Jinja2 with bytecode caching and HMAC integrity
Cache Multi-backend caching with decorators and middleware
Storage Async file storage (local, S3, GCS, Azure, SFTP, memory)
Tasks Background job system with priority queues and scheduling
Mail Multi-provider email (SMTP, SES, SendGrid)
SSE Server-Sent Events streaming (SSEResponse, SSEEvent)
WebSockets Socket controllers with event/subscription/guard decorators
Versioning Epoch-based API versioning with sunset lifecycle
OTel OpenTelemetry distributed tracing middleware and configuration
Admin Auto-detecting admin dashboard with audit logging

Testing

python -m pytest tests/ -v

python -m pytest tests/ --cov=aquilia --cov-report=html

Learn More


Built with ❤️ by the Aquilia Team

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aquilia-1.1.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aquilia-1.1.0-py3-none-any.whl (2.1 MB view details)

Uploaded Python 3

File details

Details for the file aquilia-1.1.0.tar.gz.

File metadata

  • Download URL: aquilia-1.1.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aquilia-1.1.0.tar.gz
Algorithm Hash digest
SHA256 a406e4db1a4425aa810b9806f0e05f2a93745df42d5bb2dd09556e6ace7a66b6
MD5 ccebe239c32a31009c418fb6d649a2ca
BLAKE2b-256 eee155177de5ad8e9060bf8b94fbbe8c31fe49ac1999fccc12d8f79d40fadfbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for aquilia-1.1.0.tar.gz:

Publisher: release.yml on tubox-labs/Aquilia

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aquilia-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: aquilia-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aquilia-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb905ff2b8bf5ccc0f8c589c88929244148ee7d9db40d41420c210914da77968
MD5 71afdf52c77dbb0cf7b07e19a63f3410
BLAKE2b-256 343589c3671a45c82e53320e85e932fd02f37663812558034c575dfa739b20d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for aquilia-1.1.0-py3-none-any.whl:

Publisher: release.yml on tubox-labs/Aquilia

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page