spaps-server-quickstart
Reusable FastAPI, SQLAlchemy, Celery, auth, and operational scaffolding for SPAPS-aligned Python services. This is the active backend package in this repository.
Examples in this README use placeholders such as https://api.example.test and local-only database URLs. Replace them with values from your own environment.
Install
pip install spaps-server-quickstart
This package targets Python 3.12+.
When It Fits
| Need | Package gives you |
|---|---|
| A real FastAPI starting point | create_app, settings loaders, request logging, and startup checks |
| Shared auth and RBAC | SPAPS auth middleware, auth channels, cookies, and role dependencies |
| Async database plumbing | SQLAlchemy 2 async session helpers and Alembic support |
| Operational scaffolding | Celery setup, deploy templates, local-mode helpers, and service SDK utilities |
Quick Start
from fastapi import APIRouter
from spaps_server_quickstart import create_app
from spaps_server_quickstart.settings import (
BaseServiceSettings,
create_settings_loader,
)
class ExampleSettings(BaseServiceSettings):
app_name: str = "Example Service"
spaps_auth_enabled: bool = False
router = APIRouter()
@router.get("/health")
async def health() -> dict[str, bool]:
return {"ok": True}
app = create_app(
settings_loader=create_settings_loader(ExampleSettings),
api_router=router,
)
What the Package Ships
| Area | Highlights |
|---|---|
| App lifecycle | create_app, startup validation, logging, CORS wiring |
| Auth | SpapsAuthMiddleware, auth cookies, auth channel service, local mode |
| Routing and RBAC | Base router builder, authenticated-user dependencies, require_roles, has_required_roles |
| Database | Async sessionmaker factory, migration runner, Alembic helpers |
| Tasks | Celery app factory plus notification and ping task helpers |
| Service SDK helpers | Admin token cache, server-side SPAPS clients, trusted-service middleware, feature evaluation |
| Templates | Domain examples, tests, deployment scaffolding, and local operations helpers |
| Reference contract | The golden_path app blueprint, seeded paid-access policy, and downstream runbook for the core auth -> billing -> entitlement -> access loop |
Golden App Pack
If you want one SPAPS-native reference contract instead of a blank scaffold, start with the golden_path blueprint.
It is the canonical pack for:
- browser auth and one-call session bootstrap via
GET /api/auth/session-context - Stripe checkout or subscription flows
- entitlement projection into
paid_access - policy-gated access through the seeded
access-paid-featuresrule - an operator runbook under
docs/downstream_apps/golden-path-reference/
Local Development Mode
For the SPAPS app in this repo, SPAPS_LOCAL_MODE is the canonical local
auth/persona switch. It controls the route dependencies in
middleware/spaps_deps.py: missing API keys fall back to the local test
application, missing JWTs fall back to the selected test persona, explicit API
keys still validate normally, and real JWTs still win when present.
ENV |
SPAPS_LOCAL_MODE |
SPAPS app behavior |
|---|---|---|
prod / production |
unset or false |
local mode off; real API key/JWT required |
prod / production |
true |
startup fails; bypass is not allowed |
dev / development / test |
unset | local mode on by default |
dev / development / test |
true |
local mode on |
dev / development / test |
false |
local mode off |
staging / ci |
unset | local mode off unless explicitly enabled |
| unknown env | any | production-strict; local bypass is disabled |
Check the resolved state with /health/local-mode, /health/ready, or the
X-SPAPS-Mode response header. X-SPAPS-Environment carries the normalized
environment used for the safety decision.
DEVELOPMENT_ENVIRONMENT=local is the base quickstart/template knob for
services that explicitly wire LocalAuthMiddleware; it is not the SPAPS app
runtime switch.
from spaps_server_quickstart.local_mode import (
LocalAuthMiddleware,
get_default_registry,
)
from spaps_server_quickstart.settings import BaseServiceSettings
settings = BaseServiceSettings(development_environment="local")
if settings.is_local_development:
app.add_middleware(LocalAuthMiddleware, registry=get_default_registry())
Default personas:
| Persona | Token | Roles |
|---|---|---|
| Admin | local-admin |
admin, user |
| User | local-user |
user |
Configuration
Common settings exposed through BaseServiceSettings:
| Setting | Purpose |
|---|---|
spaps_local_mode |
Canonical SPAPS app local auth/persona switch |
development_environment |
Base-template LocalAuthMiddleware switch when set to local; not the SPAPS app mode switch |
spaps_auth_enabled |
Turns SPAPS auth middleware on or off |
spaps_auth_exempt_paths |
Comma-separated paths that skip SPAPS auth |
cors_allow_origins |
Shared CORS configuration |
database_url |
Async SQLAlchemy database URL |
redis_url |
Redis URL used by Celery defaults |
secure_messages_enabled |
Enables secure-messaging gateway support |
For per-process local origins that should not live in environment settings, pass them to the app factory:
app = create_app(
settings_loader=create_settings_loader(ExampleSettings),
api_router=router,
extra_cors_origins=["http://localhost:5173"],
)
When settings origins are empty, extra_cors_origins enables CORS only for
those explicit origins. It does not add the wildcard origin unless CORS is
enabled manually without any configured origins.
Example environment:
SPAPS_LOCAL_MODE=true
# Only set DEVELOPMENT_ENVIRONMENT=local for downstream services that wire LocalAuthMiddleware.
SPAPS_API_URL=https://api.example.test
SPAPS_API_KEY=spaps_sec_example
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/service
SPAPS_AUTH_EXEMPT_PATHS=/health,/docs
CORS_ALLOW_ORIGINS=http://localhost:3000,http://localhost:5173
Validation
From the repository root, the Makefile is the canonical workflow:
make install
make pytest
make lint
make typecheck
make pytest-cov
make test
Useful additional commands:
make pytest-full
make pytest PYTEST_ARGS='tests/properties'
make migration-lint
make migration-downgrade-check
make migrate
make migrate-rehearsal
make perf-bench
make perf-k6
make new-migration MSG="add_example_table"
make local-up
The tests/properties/ suite uses deterministic Hypothesis checks for pure
security helpers: wallet canonicalization, nonce parsing, publishable route
scope matching, rate-limit tier resolution, one-time auth challenges, and
webhook HMAC signing.
make migration-lint checks Alembic migrations changed from BASE_REF for
rollback and production-lock hazards. make migrate-rehearsal reuses the
existing production-dump restore path, applies migrations, and writes a timing
report under .skillbox/reports/. The restore path renders the cached dump
through scripts/dev/restore_prod_dump_stream.py so local-only placeholder rows
can satisfy FK validation for known historical dump orphans without disabling
constraints.
make perf-bench runs the opt-in pytest-benchmark hot-path suite and compares
the result with committed budgets under tests/benchmarks/baselines/.
make perf-k6 runs the k6 scenario against SPAPS_E2E_TARGET after a local
stack is already running. These targets are report-only; normal PR validation
does not execute performance measurements.
Troubleshooting
make pytest reports no affected tests
That is expected when testmon sees no impacted tests. Use make pytest-full when you need a full run.
Local auth bypass is not active
For the SPAPS app, check /health/local-mode, /health/ready, X-SPAPS-Mode,
and the SPAPS_LOCAL_MODE value. For generated services using the base
quickstart middleware, confirm DEVELOPMENT_ENVIRONMENT=local is set before
startup and that LocalAuthMiddleware is wired into the app.
Unauthenticated routes still require auth
Check spaps_auth_exempt_paths and make sure the configured paths match the router paths exactly.
Startup fails on environment validation
Review the required settings and any safety checks triggered during startup.
I need a new service quickly
Start from the included templates, then keep the repo-root validation path intact while adapting domain code and settings.
Limitations
- This package is a scaffold, not a finished application.
- Downstream services still need their own routers, schemas, repositories, and deployment settings.
- Some operational templates intentionally need environment-specific edits before production use.
FAQ
Is this the active backend package in this repo?
Yes. This package replaces the old Node/Express stack as the active backend surface.
Does it include local auth bypass support?
Yes. The SPAPS app uses SPAPS_LOCAL_MODE; generated services can still use
DEVELOPMENT_ENVIRONMENT=local with the local-mode helpers.
Can I use it without Celery?
Yes. Celery helpers are included, but you can compose only the pieces your service needs.
Does it include RBAC helpers?
Yes. Use require_roles, has_required_roles, and the authenticated-user dependencies.
What is the recommended validation path here?
From the repository root: make pytest, make lint, make typecheck, make pytest-cov, and make test.
Metadata
package_name:spaps-server-quickstartlatest_version:0.6.4minimum_runtime:Python >=3.12api_base_url:https://api.sweetpotato.dev
About Contributions
About Contributions: Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via
ghand independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spaps_server_quickstart-0.6.5.tar.gz.
File metadata
- Download URL: spaps_server_quickstart-0.6.5.tar.gz
- Upload date:
- Size: 1.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0be762d0d39f8f88a982c20a074a49d7508d7d5e76b4396d2f13b183e75113fe
|
|
| MD5 |
99efd001e78f983706fcf1fd678fb4ba
|
|
| BLAKE2b-256 |
81267692f839dcf12d05d00842693350b85fa7f4ec21c4ae0e358a47d467afc0
|
File details
Details for the file spaps_server_quickstart-0.6.5-py3-none-any.whl.
File metadata
- Download URL: spaps_server_quickstart-0.6.5-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7787a17c9e2b81a9aca69b5c3dc892f7db77132207686a10ca2cb6dc0d0d2f35
|
|
| MD5 |
3270989e03685a35e1e163d725fa891b
|
|
| BLAKE2b-256 |
d40a997746d9d20ffde01702ad0abf7400ac9ca8d8741f84c88f6fd7e9cac80f
|