Skip to main content

Shared FastAPI/Celery scaffolding for Sweet Potato service backends.

Project description

SPAPS Server Quickstart

Reusable scaffolding for Sweet Potato service backends. This package gathers the FastAPI application factory, Celery bootstrap, Pydantic settings base classes, and other utilities that HTMA, Ingredient, and future services can share.

Installation

Use either Poetry (preferred inside this repo) or pip editable installs:

# with poetry
poetry install -C packages/python-server-quickstart

# or with pip (installs package + dev extras)
python3 -m pip install -e 'packages/python-server-quickstart[dev]'

The editable install ensures FastAPI, SQLAlchemy, Celery, and other dependencies are available when the pre-push scripts execute.

Local Development

poetry run -C packages/python-server-quickstart pytest

The shared modules are designed to be imported by individual service packages. Tests live alongside the shared code to guard the common behaviour.

Local Auth Bypass Mode

For local development without external auth services, enable local mode by setting DEVELOPMENT_ENVIRONMENT=local. This provides pre-configured personas (admin/user) that bypass SPAPS authentication.

from spaps_server_quickstart.settings import BaseServiceSettings
from spaps_server_quickstart.local_mode import (
    LocalAuthMiddleware,
    get_default_registry,
)

settings = BaseServiceSettings(development_environment="local")

if settings.is_local_development:
    app.add_middleware(LocalAuthMiddleware, registry=get_default_registry())

Available personas:

Persona Token Roles
Admin local-admin admin, user
User local-user user

Use the token in your Authorization header: Authorization: Bearer local-admin

Optional local auth routes are available under spaps_server_quickstart.templates.domains.auth.local_routes:

from spaps_server_quickstart.templates.domains.auth.local_routes import router as local_auth_router

if settings.is_local_development:
    app.include_router(local_auth_router, prefix="/v1/auth", tags=["local-auth"])

This adds:

  • GET /v1/auth/local-personas - List available personas
  • POST /v1/auth/local-login - Login with persona code or token
  • GET /v1/auth/local-me - Get current persona from Authorization header

Operational Templates

For infrastructure parity with live SPAPS services, the directory templates/operations contains a ready-to-copy bundle that now includes:

  • Makefile with lint/test/deploy shortcuts
  • Production .env.production.example
  • Docker Compose + reverse-proxy stubs (pre-configured with Docker DNS resolver support)
  • Deploy script that reloads the shared proxy in-place after each rollout
  • Pre/post deployment checks (pre-deploy-checks.sh, post-deploy-verify.sh)
  • Database maintenance scripts (backup-db.sh, restore-db.sh, new-migration.sh)
  • Pre-push hook + scripts/prepush.sh matching live automation
  • Local Postgres helpers under scripts/dev/ (start-db.sh, stop-db.sh, await_db.py) for pgvector-backed test runs

Deployment Checks

The deployment scripts include automated validation:

Pre-deployment (pre-deploy-checks.sh):

  • Docker availability and daemon status
  • Port availability for required services
  • Disk space validation (configurable minimum)
  • Required environment variable validation
  • Dev container conflict detection
  • Docker network verification

Post-deployment (post-deploy-verify.sh):

  • Container running status
  • Health endpoint validation with exponential backoff
  • Image version verification
  • Migration status check (optional)
  • Docker healthcheck status
  • Service connectivity (Redis, database)

Configuration via environment variables:

Variable Description Default
SERVICE_NAME Service identifier for checks quickstart
REQUIRED_PORTS Comma-separated ports to check 8000
MIN_DISK_SPACE_GB Minimum disk space required 5
REQUIRED_ENV_VARS Required environment variables ``
HEALTH_ENDPOINT URL for health check http://localhost:8000/health
MAX_HEALTH_WAIT Max seconds to wait for health 60
SKIP_PRE_CHECKS Skip pre-deployment checks 0
SKIP_POST_CHECKS Skip post-deployment checks 0

Database Caching for Local Development

The local-debug-loop.sh script caches seeded database state to speed up make local-up:

# First run: seeds database and creates cache
make local-up

# Subsequent runs: restores from cache if seeds/migrations unchanged
make local-up

# Force full reseed (ignores cache)
make local-up-seed

# Watch mode: auto-reseeds when files change
make local-up-watch

How it works:

  1. Computes SHA256 hash of alembic/, scripts/seeds/, fixtures/ directories
  2. If hash matches cached version, restores database from pg_dump cache
  3. If hash differs, runs full migrations + seeds, then saves new cache
  4. Cache stored at ~/.cache/${SERVICE_NAME}/db/seeded.sql.gz

Configuration:

Variable Description Default
SERVICE_NAME Service name for cache paths quickstart
CACHE_ROOT Base cache directory ~/.cache/${SERVICE_NAME}
FORCE_RESEED Force full reseed ignoring cache 0
SKIP_DB_CACHE Disable caching entirely 0
CACHE_TARGETS Directories to include in hash alembic scripts/seeds fixtures
LOCAL_WATCH Enable watch mode for auto-reseed 0

Copy the folder into a service repository when adopting the quickstart so CI/CD, GHCR pulls, backup automation, and the shared reverse proxy follow the same playbook used by Ingredient, HTMA, and Sweet Potato. Update the provided environment variables (PROJECT_SLUG, DB_SERVICE, etc.) after copying to match the new service naming.

The reverse proxy template adds resolver 127.0.0.11 ipv6=off valid=30s; and marks upstream servers with resolve so nginx re-resolves Docker service names whenever containers cycle. During deployment the helper issues docker exec shared-reverse-proxy nginx -s reload (falling back to the legacy ./up.sh script) so configuration changes take effect without bouncing the proxy container.

When developing locally, start the database with scripts/dev/start-db.sh before running scripts/prepush.sh or pytest. The helper waits for a pgvector-enabled Postgres on port 5433 and seeds PYTEST_DATABASE_URL, DATABASE_URL, and SYNC_DATABASE_URL with sensible defaults. Shut it down with scripts/dev/stop-db.sh.

RBAC Helpers & Sample Routers

  • Use spaps_server_quickstart.rbac.require_roles as a FastAPI dependency to guard admin/staff-only routes. It returns the authenticated user when the role check passes and raises HTTPException (401/403) otherwise.
  • spaps_server_quickstart.rbac.has_required_roles provides a lightweight predicate when you need to branch on roles outside of dependency injection.
  • Copy the sample routers under spaps_server_quickstart.templates.domains (users/admin) when spinning up new services—they demonstrate how to wire the RBAC helpers into typical CRUD endpoints.

Configuration Highlights

Services configure behaviour by subclassing BaseServiceSettings. Override fields like spaps_auth_exempt_paths to expose unauthenticated endpoints or set cors_allow_origins (and related CORS knobs) to attach the shared CORSMiddleware without writing per-service plumbing. All list-like settings accept comma-separated environment variables for easy deployment.

Auth Channels (Magic Link & Wallet)

  • SpapsAuthChannelService wraps SPAPS magic-link and wallet authentication so services can drop the boilerplate client calls.
  • Use send_magic_link / verify_magic_link for email links and request_wallet_nonce / verify_wallet for Solana or Ethereum sign-ins.
  • The helpers raise AuthChannelError with status_code and error_code, giving your routes enough context to map responses cleanly.
  • Lifecycle management mirrors the main auth service—call await service.aclose() during shutdown if you create a long-lived instance.

Secure Messaging Gateway

  • spaps_server_quickstart.secure_messaging.build_secure_messaging_gateway returns an async gateway mirroring HTMA’s SPAPS secure messaging integration. It logs send/list operations and normalises upstream failures into SecureMessagingGatewayError.
  • provide_secure_messaging_gateway enforces feature flags and required roles before returning a configured gateway. Wire it into FastAPI dependencies to replicate practitioner-only messaging flows without bespoke plumbing.
  • SecureMessagingContext carries practitioner/patient identifiers and optional access tokens; the helper merges default metadata (application_id, practitioner_user_id) so downstream analytics remain consistent across services.
  • Settings expose secure_messages_enabled, secure_messages_timeout, and secure_messages_default_page_size, letting each service toggle secure messaging per environment.

Auth Dependencies

  • spaps_server_quickstart.auth.dependencies.require_authenticated_user retrieves the AuthenticatedUser assigned by SpapsAuthMiddleware, raising a 401 when the request lacks credentials.
  • require_authenticated_role("role") returns a dependency that asserts the subject holds a given role (case-insensitive), raising a 403 otherwise. Use it for common admin/practitioner guardrails without reimplementing role checks.

Environment Reference

Variable Description Notes
DEVELOPMENT_ENVIRONMENT Set to local to enable local auth bypass Defaults to None
SPAPS_API_URL Base URL for SPAPS API requests Defaults to https://api.sweetpotato.dev
SPAPS_API_KEY Service API key used for auth + channel helpers Required when spaps_auth_enabled is true
SPAPS_APPLICATION_ID Application identifier enforced during session validation Required when spaps_auth_enabled is true
SPAPS_AUTH_ENABLED Toggle for the auth middleware Enables SpapsAuthMiddleware when true
SPAPS_AUTH_EXEMPT_PATHS Comma-separated paths that bypass auth Parsed into a tuple automatically
SPAPS_REQUEST_TIMEOUT Timeout (seconds) for SPAPS HTTP calls Applies to both auth and channel helpers
CORS_ALLOW_ORIGINS / CORS_ALLOW_METHODS / CORS_ALLOW_HEADERS Comma-separated CORS configuration Leave empty to skip the middleware
CORS_EXPOSE_HEADERS Headers exposed to clients Defaults to empty tuple
CORS_ALLOW_CREDENTIALS Whether CORS requests include credentials Defaults to true
CORS_MAX_AGE CORS preflight cache duration Must be non-negative
SECURE_MESSAGES_ENABLED Toggle SPAPS secure messaging gateway wiring Defaults to false
SECURE_MESSAGES_TIMEOUT Override secure messaging request timeout Falls back to SPAPS_REQUEST_TIMEOUT
SECURE_MESSAGES_DEFAULT_PAGE_SIZE Default list_messages page size Must be positive

Lifecycle Hooks

create_app now uses FastAPI's lifespan context to close shared resources (e.g., SPAPS auth clients). When you need additional startup/shutdown logic, extend the lifespan in your service by wrapping the provided app with your own context manager or closing resources within your domain packages. Running tests with TestClient(app) will automatically exercise the shutdown path and catch missing aclose() implementations. Pair this with spaps_server_quickstart.db.collect_migration_status inside custom health metrics providers to surface Alembic drift on /health (mirroring HTMA’s practitioner metrics).

Upgrading Downstream Services

Guidance for publishing new versions and upgrading consumer services lives in docs/UPGRADING.md. Review those steps before bumping the package or pulling a newer release into htma_server, ingredient_server, or other SPAPS services.

Migrating an Existing Service

See docs/MIGRATION_GUIDE.md for a step-by-step walkthrough of adopting the shared package inside an existing FastAPI/Celery service. It covers settings integration, router wiring, database session management, Celery bootstraps, and the final cleanup checklist.

Release Workflow

  • Use the GitHub Action Publish Python Server Quickstart (.github/workflows/python-server-quickstart-release.yml) to cut releases. It reuses the generic python-package-release workflow alongside scripts/manage_python_package_version.py.
  • Ensure the repository secret PYPI_SERVER_QUICKSTART_TOKEN holds the PyPI API token for this package.
  • For manual bumps, dispatch the workflow and choose the bump type (major/minor/patch). For automated publishes, pushing a commit that updates packages/python-server-quickstart/pyproject.toml will trigger the workflow.

Status

  • Initial package scaffold
  • Shared application factories
  • Shared Celery bootstrap
  • Shared middleware, logging, and settings base classes
  • Health endpoint helpers
  • Documentation and usage examples

Repository Integration

The root package.json includes lint:python-server-quickstart, typecheck:python-server-quickstart, and test:python-server-quickstart commands. These run automatically via npm run prepush, and the npm scripts install packages/python-server-quickstart[dev] on demand so the editable install step is handled for you.

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

spaps_server_quickstart-0.3.0.tar.gz (148.8 kB view details)

Uploaded Source

Built Distribution

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

spaps_server_quickstart-0.3.0-py3-none-any.whl (118.8 kB view details)

Uploaded Python 3

File details

Details for the file spaps_server_quickstart-0.3.0.tar.gz.

File metadata

  • Download URL: spaps_server_quickstart-0.3.0.tar.gz
  • Upload date:
  • Size: 148.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for spaps_server_quickstart-0.3.0.tar.gz
Algorithm Hash digest
SHA256 f66bd6493364c38be8e3acc690da548b5fa6d34fd0425720482bb0768bd5e015
MD5 e06c672dc9cf197fb4159d7b75aa3836
BLAKE2b-256 09f8a9734ebdf2a5f6f9d5add203a2ba4e13d45a5ef00fae17803c1dc5a98cfd

See more details on using hashes here.

File details

Details for the file spaps_server_quickstart-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for spaps_server_quickstart-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d0bc66d180b6915f77afc65fd43911efd48543e398915d8092195f800a0c600c
MD5 9687d8479ea1cddfe943e8190bae476b
BLAKE2b-256 0ec3d10d213ee148b32888d39846be75ff3a1f8d1db787f35518e483362bc17f

See more details on using hashes here.

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