Contracts — Aquilia Documentation
Comprehensive guide and documentation for Contracts in the Aquilia framework. View API reference, examples, and implementation patterns.
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(( ) => ( ))} )
Go to Homepage