Architecture
SPAPS follows a layered backend shape: a FastAPI app factory composes routers, middleware handles cross-cutting concerns, domain routers call services, services coordinate repositories and integrations, and repositories own database access. The package also exports reusable scaffolding so another Python service can adopt the same conventions without importing the full SPAPS app.
System View
Entry Points
| Entry point | File | Responsibility |
|---|---|---|
create_spaps_app | packages/python-server-quickstart/src/spaps_server_quickstart/spaps_app.py | Builds the full SPAPS app, imports models, wires lifespan checks, mounts all domain routers, and stores settings plus DB resources on app.state |
app | packages/python-server-quickstart/src/spaps_server_quickstart/spaps_app.py | Module-level ASGI app for uvicorn spaps_server_quickstart.spaps_app:app |
create_app | packages/python-server-quickstart/src/spaps_server_quickstart/app_factory.py | Reusable FastAPI factory for downstream services |
create_celery_app | packages/python-server-quickstart/src/spaps_server_quickstart/tasks/celery_factory.py | Shared Celery setup from service settings |
Middleware Order
The full SPAPS app installs ten material layers in create_spaps_app. Registration order matters
because Starlette executes the last-added middleware first; CORS preflight, canonical paths,
request IDs, limits, and JSON envelopes can all change user-visible responses.
PasskeyVerifyBodyLimitMiddleware
ResponseEnvelopeMiddleware
PrometheusMetricsMiddleware
RateLimitMiddleware
CORSMiddleware
ApplicationOriginCORSMiddleware # conditional: DB-backed application origins
SpapsModeHeaderMiddleware
RequestLoggingMiddleware
NativeAuthCanonicalPathMiddleware
SecurityHeadersMiddlewareDomain Boundary
Most product folders under domains/ use the same shape:
domains/<domain>/
router.py # FastAPI route handlers
service.py # business orchestration
repository.py # SQLAlchemy queries
models.py # database models
schemas.py # Pydantic request/response modelsSome domains are intentionally smaller. For example, self_service has router, service, and
schemas but no repository file.
Reusable Package Boundary
The package root exports create_app, settings, DB helpers, RBAC helpers, auth channel helpers, migration naming utilities, task helpers, and server-side SDK utilities from __init__.py. This makes the package useful outside the concrete SPAPS app.
Next
- Request lifecycle gives the flow in request order.
- App factory reference documents the reusable factory.
- Domain catalog maps the product folders.