Metadata-Version: 2.4
Name: spaps-server-quickstart
Version: 0.6.3
Summary: Shared FastAPI/Celery scaffolding for Sweet Potato service backends.
Project-URL: Homepage, https://api.sweetpotato.dev
Project-URL: Repository, https://github.com/sweet-potato/spaps
Author-email: buildooor <buildooor@gmail.com>
License: MIT
Keywords: celery,fastapi,quickstart,spaps,sweet-potato
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.12
Requires-Dist: aioboto3<14.0,>=13.3.0
Requires-Dist: alembic<2.0,>=1.13.1
Requires-Dist: asyncpg<0.31,>=0.30.0
Requires-Dist: bcrypt<6.0,>=4.0.0
Requires-Dist: botocore<2.0,>=1.35.0
Requires-Dist: celery<6.0,>=5.5.3
Requires-Dist: cryptography<49.0,>=46.0.7
Requires-Dist: email-validator<3.0,>=2.1.0
Requires-Dist: eth-account<1.0,>=0.13.0
Requires-Dist: fastapi<1.0,>=0.120.0
Requires-Dist: greenlet<4.0,>=3.0.3
Requires-Dist: httpcore<2.0,>=1.0.9
Requires-Dist: httpx<0.29,>=0.28.1
Requires-Dist: orjson<4.0,>=3.10.0
Requires-Dist: packaging<27.0,>=23.0
Requires-Dist: pgvector<0.5,>=0.4.1
Requires-Dist: psycopg[binary]<3.3,>=3.2.10
Requires-Dist: pydantic-settings<3.0,>=2.3.0
Requires-Dist: pydantic<3.0,>=2.8.0
Requires-Dist: pyjwt<3.0,>=2.8.0
Requires-Dist: python-dotenv<2.0,>=1.0.1
Requires-Dist: python-multipart<0.1,>=0.0.20
Requires-Dist: redis<7.0,>=6.4.0
Requires-Dist: slowapi<1.0,>=0.1.9
Requires-Dist: solders<1.0,>=0.21.0
Requires-Dist: spaps>=0.1.2
Requires-Dist: sqlalchemy<3.0,>=2.0.30
Requires-Dist: starlette<2.0,>=0.49.1
Requires-Dist: stripe<12.0,>=8.0.0
Requires-Dist: structlog<26.0,>=25.4.0
Requires-Dist: uvicorn[standard]<0.38,>=0.37.0
Requires-Dist: x402[extensions,fastapi,svm]==2.9.0
Provides-Extra: dev
Requires-Dist: anyio<5.0,>=4.4.0; extra == 'dev'
Requires-Dist: bcrypt<6.0,>=4.0.0; extra == 'dev'
Requires-Dist: coverage<8.0,>=7.4.0; extra == 'dev'
Requires-Dist: docker<8.0,>=7.0.0; extra == 'dev'
Requires-Dist: filelock<4.0,>=3.12.0; extra == 'dev'
Requires-Dist: httpx<0.29,>=0.28.1; extra == 'dev'
Requires-Dist: mypy<1.12,>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio<0.24,>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov<6.0,>=5.0.0; extra == 'dev'
Requires-Dist: pytest-testmon<3.0,>=2.1.0; extra == 'dev'
Requires-Dist: pytest-xdist<4.0,>=3.6.1; extra == 'dev'
Requires-Dist: pytest<9.0,>=8.2.0; extra == 'dev'
Requires-Dist: respx<0.23,>=0.22.0; extra == 'dev'
Requires-Dist: ruff<0.5,>=0.4.1; extra == 'dev'
Requires-Dist: testcontainers[postgres]<5.0,>=4.0.0; extra == 'dev'
Requires-Dist: types-pyyaml<7.0,>=6.0.0; extra == 'dev'
Provides-Extra: release
Requires-Dist: build<2.0,>=1.2.1; extra == 'release'
Requires-Dist: twine<6.0,>=5.0.0; extra == 'release'
Provides-Extra: testing
Requires-Dist: docker<8.0,>=7.0.0; extra == 'testing'
Requires-Dist: filelock<4.0,>=3.12.0; extra == 'testing'
Requires-Dist: httpx<0.29,>=0.28.1; extra == 'testing'
Requires-Dist: pytest-asyncio<0.24,>=0.23.0; extra == 'testing'
Requires-Dist: pytest-testmon<3.0,>=2.1.0; extra == 'testing'
Requires-Dist: pytest-xdist<4.0,>=3.6.1; extra == 'testing'
Requires-Dist: pytest<9.0,>=8.2.0; extra == 'testing'
Requires-Dist: respx<0.23,>=0.22.0; extra == 'testing'
Requires-Dist: testcontainers[postgres]<5.0,>=4.0.0; extra == 'testing'
Description-Content-Type: text/markdown

# 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

```bash
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

```python
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 session bootstrap
- Stripe checkout or subscription flows
- entitlement projection into `paid_access`
- policy-gated access through the seeded `access-paid-features` rule
- an operator runbook under `docs/downstream_apps/golden-path-reference/`

## Local Development Mode

Set `DEVELOPMENT_ENVIRONMENT=local` to enable local auth bypass in development and tests.

```python
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 |
| --- | --- |
| `development_environment` | Enables local bypass mode when set to `local` |
| `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:

```python
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:

```bash
DEVELOPMENT_ENVIRONMENT=local
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:

```bash
make install
make pytest
make lint
make typecheck
make pytest-cov
make test
```

Useful additional commands:

```bash
make pytest-full
make migrate
make new-migration MSG="add_example_table"
make local-up
```

## 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

Confirm `DEVELOPMENT_ENVIRONMENT=local` is set before application 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. Set `DEVELOPMENT_ENVIRONMENT=local` and wire in 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-quickstart`
- `latest_version`: `0.6.2`
- `minimum_runtime`: `Python >=3.12`
- `api_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 `gh` and 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
