spaps-server-quickstart 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. spaps_server_quickstart-0.0.1/.coverage +0 -0
  2. spaps_server_quickstart-0.0.1/.gitignore +132 -0
  3. spaps_server_quickstart-0.0.1/CHANGELOG.md +16 -0
  4. spaps_server_quickstart-0.0.1/PKG-INFO +102 -0
  5. spaps_server_quickstart-0.0.1/README.md +71 -0
  6. spaps_server_quickstart-0.0.1/docs/MIGRATION_GUIDE.md +104 -0
  7. spaps_server_quickstart-0.0.1/docs/UPGRADING.md +82 -0
  8. spaps_server_quickstart-0.0.1/pyproject.toml +62 -0
  9. spaps_server_quickstart-0.0.1/scripts/release.sh +23 -0
  10. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/__init__.py +63 -0
  11. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/alembic/__init__.py +21 -0
  12. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/alembic/naming.py +137 -0
  13. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/api/__init__.py +7 -0
  14. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/api/health.py +98 -0
  15. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/api/router.py +30 -0
  16. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/app_factory.py +97 -0
  17. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/auth.py +232 -0
  18. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/db/__init__.py +17 -0
  19. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/db/migration_runner.py +81 -0
  20. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/db/session.py +99 -0
  21. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/logging.py +69 -0
  22. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/middleware.py +50 -0
  23. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/schemas/__init__.py +7 -0
  24. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/schemas/health.py +23 -0
  25. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/settings.py +144 -0
  26. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/tasks/__init__.py +13 -0
  27. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/tasks/celery_factory.py +40 -0
  28. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/tasks/health.py +31 -0
  29. spaps_server_quickstart-0.0.1/src/spaps_server_quickstart/tasks/notifications.py +41 -0
  30. spaps_server_quickstart-0.0.1/tests/test_alembic_naming.py +52 -0
  31. spaps_server_quickstart-0.0.1/tests/test_api_router.py +23 -0
  32. spaps_server_quickstart-0.0.1/tests/test_app_factory.py +122 -0
  33. spaps_server_quickstart-0.0.1/tests/test_auth.py +72 -0
  34. spaps_server_quickstart-0.0.1/tests/test_db_session.py +124 -0
  35. spaps_server_quickstart-0.0.1/tests/test_health_router.py +74 -0
  36. spaps_server_quickstart-0.0.1/tests/test_imports.py +28 -0
  37. spaps_server_quickstart-0.0.1/tests/test_logging.py +39 -0
  38. spaps_server_quickstart-0.0.1/tests/test_middleware.py +45 -0
  39. spaps_server_quickstart-0.0.1/tests/test_migration_runner.py +35 -0
  40. spaps_server_quickstart-0.0.1/tests/test_settings.py +46 -0
  41. spaps_server_quickstart-0.0.1/tests/test_tasks.py +78 -0
  42. spaps_server_quickstart-0.0.1/todo.md +56 -0
Binary file
@@ -0,0 +1,132 @@
1
+ # Dependencies
2
+ node_modules/
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+
9
+ # Testing
10
+ coverage/
11
+ *.lcov
12
+ .nyc_output
13
+ packages/python-client/.coverage
14
+
15
+ # Production builds
16
+ dist/
17
+ build/
18
+ out/
19
+ *.tsbuildinfo
20
+
21
+ # Environment files
22
+ .env
23
+ .env.*
24
+ *.env
25
+ **/.env
26
+ **/.env.*
27
+ .env.development
28
+ .env.production
29
+ .env.staging
30
+ .env.deploy
31
+ .env.local
32
+ .env.development.local
33
+ .env.test.local
34
+ .env.production.local
35
+ # Allow committed templates/examples
36
+ !*.env.example
37
+ !*.env.sample
38
+ !*.env.template
39
+ !**/.env.example
40
+ !**/.env.sample
41
+ !**/.env.template
42
+ !**/.env.*.example
43
+ !**/.env.*.sample
44
+ !**/.env.*.template
45
+ !**/*.env.example
46
+ !**/*.env.sample
47
+ !**/*.env.template
48
+
49
+ # IDE
50
+ .vscode/
51
+ .idea/
52
+ *.swp
53
+ *.swo
54
+ *.swn
55
+ .DS_Store
56
+
57
+ # Debug
58
+ debug.log
59
+ *.log
60
+
61
+ # Temporary files
62
+ tmp/
63
+ temp/
64
+ *.tmp
65
+ packages/python-client/**/__pycache__/
66
+
67
+ # Package manager files
68
+ .pnp.*
69
+ .yarn/*
70
+ !.yarn/patches
71
+ !.yarn/plugins
72
+ !.yarn/releases
73
+ !.yarn/sdks
74
+ !.yarn/versions
75
+
76
+ # Next.js specific
77
+ .next/
78
+ next-env.d.ts
79
+ .vercel/
80
+
81
+ # Example projects - ignore build artifacts
82
+ examples/**/.next/
83
+ examples/**/node_modules/
84
+ examples/**/dist/
85
+ examples/**/build/
86
+ examples/**/*.log
87
+ examples/**/.env
88
+ examples/**/.env.local
89
+
90
+ # MCP/Sweetpotato docs build
91
+ mcp-sweetpotato-docs/node_modules/
92
+ mcp-sweetpotato-docs/dist/
93
+ mcp-sweetpotato-docs/build/
94
+ mcp-sweetpotato-docs/.next/
95
+
96
+ # Large test files
97
+ *.jpg
98
+ *.jpeg
99
+ *.png
100
+ *.gif
101
+ *.bmp
102
+ *.mp4
103
+ *.mov
104
+ *.avi
105
+ *.zip
106
+ *.tar
107
+ *.gz
108
+ *.rar
109
+
110
+ # Database files
111
+ *.sqlite
112
+ *.sqlite3
113
+ *.db
114
+
115
+ # OS files
116
+ Thumbs.db
117
+ Desktop.ini
118
+
119
+ # Backup files
120
+ *.bak
121
+ *.backup
122
+ *.old
123
+
124
+ # Test output
125
+ test-results/
126
+ playwright-report/
127
+ playwright/.cache/
128
+
129
+ # Lock files that shouldn't be committed for libraries
130
+ # (keep package-lock.json for applications)
131
+ # yarn.lock
132
+ # pnpm-lock.yaml*.tgz
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
6
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ - Added FastAPI lifespan handling for SPAPS auth cleanup.
11
+ - Introduced migration guide and upgrading instructions for downstream services.
12
+ - Established comprehensive unit tests across settings, middleware, DB, Celery, and auth helpers.
13
+
14
+ ## [0.0.1] - 2025-10-14
15
+
16
+ - Initial scaffold of `spaps-server-quickstart` with shared FastAPI/Celery/DB utilities.
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: spaps-server-quickstart
3
+ Version: 0.0.1
4
+ Summary: Shared FastAPI/Celery scaffolding for Sweet Potato service backends.
5
+ Project-URL: Repository, https://github.com/sweet-potato/spaps
6
+ Author-email: Sweet Potato Team <engineering@sweetpotato.dev>
7
+ License: Proprietary
8
+ Keywords: celery,fastapi,quickstart,spaps,sweet-potato
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: alembic<2.0,>=1.13.1
11
+ Requires-Dist: asyncpg<0.31.0,>=0.30.0
12
+ Requires-Dist: celery<6.0,>=5.4.0
13
+ Requires-Dist: fastapi<0.119.0,>=0.115.0
14
+ Requires-Dist: httpx<0.29.0,>=0.27.0
15
+ Requires-Dist: pydantic-settings<3.0,>=2.3.0
16
+ Requires-Dist: pydantic<3.0,>=2.8.0
17
+ Requires-Dist: redis<6.0,>=5.0.0
18
+ Requires-Dist: spaps>=0.1.2
19
+ Requires-Dist: sqlalchemy<3.0,>=2.0.32
20
+ Requires-Dist: structlog<26.0,>=24.1.0
21
+ Requires-Dist: tenacity<9.0,>=8.3.0
22
+ Requires-Dist: uvicorn<0.38.0,>=0.29.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: anyio<5.0,>=4.4.0; extra == 'dev'
25
+ Requires-Dist: mypy<2.0,>=1.10.0; extra == 'dev'
26
+ Requires-Dist: pytest-asyncio<0.24.0,>=0.23.0; extra == 'dev'
27
+ Requires-Dist: pytest-cov<6.0,>=5.0.0; extra == 'dev'
28
+ Requires-Dist: pytest<9.0,>=8.3.0; extra == 'dev'
29
+ Requires-Dist: ruff<1.0,>=0.5.5; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # SPAPS Server Quickstart
33
+
34
+ Reusable scaffolding for Sweet Potato service backends. This package gathers the FastAPI
35
+ application factory, Celery bootstrap, Pydantic settings base classes, and other utilities
36
+ that HTMA, Ingredient, and future services can share.
37
+
38
+ ## Installation
39
+
40
+ Use either Poetry (preferred inside this repo) or pip editable installs:
41
+
42
+ ```bash
43
+ # with poetry
44
+ poetry install -C packages/python-server-quickstart
45
+
46
+ # or with pip (installs package + dev extras)
47
+ python3 -m pip install -e 'packages/python-server-quickstart[dev]'
48
+ ```
49
+
50
+ The editable install ensures FastAPI, SQLAlchemy, Celery, and other dependencies are
51
+ available when the pre-push scripts execute.
52
+
53
+ ## Local Development
54
+
55
+ ```bash
56
+ poetry run -C packages/python-server-quickstart pytest
57
+ ```
58
+
59
+ The shared modules are designed to be imported by individual service packages. Tests live
60
+ alongside the shared code to guard the common behaviour.
61
+
62
+ ## Lifecycle Hooks
63
+
64
+ `create_app` now uses FastAPI's lifespan context to close shared resources (e.g., SPAPS auth
65
+ clients). When you need additional startup/shutdown logic, extend the lifespan in your service
66
+ by wrapping the provided app with your own context manager or closing resources within your
67
+ domain packages. Running tests with `TestClient(app)` will automatically exercise the shutdown
68
+ path and catch missing `aclose()` implementations.
69
+
70
+ ## Upgrading Downstream Services
71
+
72
+ Guidance for publishing new versions and upgrading consumer services lives in
73
+ [`docs/UPGRADING.md`](docs/UPGRADING.md). Review those steps before bumping the package or
74
+ pulling a newer release into `htma_server`, `ingredient_server`, or other SPAPS services.
75
+
76
+ ## Migrating an Existing Service
77
+
78
+ See [`docs/MIGRATION_GUIDE.md`](docs/MIGRATION_GUIDE.md) for a step-by-step walkthrough of
79
+ adopting the shared package inside an existing FastAPI/Celery service. It covers settings
80
+ integration, router wiring, database session management, Celery bootstraps, and the final
81
+ cleanup checklist.
82
+
83
+ ## Release Workflow
84
+
85
+ - 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`.
86
+ - Ensure the repository secret `PYPI_SERVER_QUICKSTART_TOKEN` holds the PyPI API token for this package.
87
+ - 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.
88
+
89
+ ## Status
90
+
91
+ - [x] Initial package scaffold
92
+ - [x] Shared application factories
93
+ - [x] Shared Celery bootstrap
94
+ - [x] Shared middleware, logging, and settings base classes
95
+ - [x] Health endpoint helpers
96
+ - [ ] Documentation and usage examples
97
+
98
+ ## Repository Integration
99
+
100
+ The root `package.json` includes `lint:python-server-quickstart`, `typecheck:python-server-quickstart`,
101
+ and `test:python-server-quickstart` commands. These run automatically via `npm run prepush`, so make sure
102
+ the editable install step above has been executed before pushing commits.
@@ -0,0 +1,71 @@
1
+ # SPAPS Server Quickstart
2
+
3
+ Reusable scaffolding for Sweet Potato service backends. This package gathers the FastAPI
4
+ application factory, Celery bootstrap, Pydantic settings base classes, and other utilities
5
+ that HTMA, Ingredient, and future services can share.
6
+
7
+ ## Installation
8
+
9
+ Use either Poetry (preferred inside this repo) or pip editable installs:
10
+
11
+ ```bash
12
+ # with poetry
13
+ poetry install -C packages/python-server-quickstart
14
+
15
+ # or with pip (installs package + dev extras)
16
+ python3 -m pip install -e 'packages/python-server-quickstart[dev]'
17
+ ```
18
+
19
+ The editable install ensures FastAPI, SQLAlchemy, Celery, and other dependencies are
20
+ available when the pre-push scripts execute.
21
+
22
+ ## Local Development
23
+
24
+ ```bash
25
+ poetry run -C packages/python-server-quickstart pytest
26
+ ```
27
+
28
+ The shared modules are designed to be imported by individual service packages. Tests live
29
+ alongside the shared code to guard the common behaviour.
30
+
31
+ ## Lifecycle Hooks
32
+
33
+ `create_app` now uses FastAPI's lifespan context to close shared resources (e.g., SPAPS auth
34
+ clients). When you need additional startup/shutdown logic, extend the lifespan in your service
35
+ by wrapping the provided app with your own context manager or closing resources within your
36
+ domain packages. Running tests with `TestClient(app)` will automatically exercise the shutdown
37
+ path and catch missing `aclose()` implementations.
38
+
39
+ ## Upgrading Downstream Services
40
+
41
+ Guidance for publishing new versions and upgrading consumer services lives in
42
+ [`docs/UPGRADING.md`](docs/UPGRADING.md). Review those steps before bumping the package or
43
+ pulling a newer release into `htma_server`, `ingredient_server`, or other SPAPS services.
44
+
45
+ ## Migrating an Existing Service
46
+
47
+ See [`docs/MIGRATION_GUIDE.md`](docs/MIGRATION_GUIDE.md) for a step-by-step walkthrough of
48
+ adopting the shared package inside an existing FastAPI/Celery service. It covers settings
49
+ integration, router wiring, database session management, Celery bootstraps, and the final
50
+ cleanup checklist.
51
+
52
+ ## Release Workflow
53
+
54
+ - 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`.
55
+ - Ensure the repository secret `PYPI_SERVER_QUICKSTART_TOKEN` holds the PyPI API token for this package.
56
+ - 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.
57
+
58
+ ## Status
59
+
60
+ - [x] Initial package scaffold
61
+ - [x] Shared application factories
62
+ - [x] Shared Celery bootstrap
63
+ - [x] Shared middleware, logging, and settings base classes
64
+ - [x] Health endpoint helpers
65
+ - [ ] Documentation and usage examples
66
+
67
+ ## Repository Integration
68
+
69
+ The root `package.json` includes `lint:python-server-quickstart`, `typecheck:python-server-quickstart`,
70
+ and `test:python-server-quickstart` commands. These run automatically via `npm run prepush`, so make sure
71
+ the editable install step above has been executed before pushing commits.
@@ -0,0 +1,104 @@
1
+ # Migrating a Service to `spaps-server-quickstart`
2
+
3
+ This playbook describes the concrete steps for services like `htma_server` and
4
+ `ingredient_server` to replace local scaffolding with the shared package. Expect a
5
+ single PR per service.
6
+
7
+ ## 1. Prepare the Service
8
+
9
+ 1. **Pin the dependency**
10
+ - Add `spaps-server-quickstart = "^0.x"` to the service `pyproject.toml`.
11
+ - `poetry update spaps-server-quickstart` (or pip equivalent) and commit the lockfile.
12
+ 2. **Install tooling**
13
+ - Ensure the editable install exists locally: `python3 -m pip install -e 'packages/python-server-quickstart[dev]'`.
14
+ - Run the shared package tests once: `npm run test:python-server-quickstart`.
15
+
16
+ ## 2. Settings & Configuration
17
+
18
+ 1. Replace the local `Settings` class with a subclass of `spaps_server_quickstart.settings.BaseServiceSettings`.
19
+ ```python
20
+ from spaps_server_quickstart.settings import BaseServiceSettings, create_settings_loader
21
+
22
+ class Settings(BaseServiceSettings):
23
+ app_name: str = "HTMA Server"
24
+ service_slug: str = "htma-server"
25
+ database_url: str = "postgresql+asyncpg://.../htma"
26
+ # include service-specific fields (e.g., practitioners, ingredient keys)
27
+
28
+ get_settings = create_settings_loader(Settings)
29
+ ```
30
+ 2. Update imports wherever `Settings` or `get_settings` were used (app factory, dependencies, tasks).
31
+
32
+ ## 3. FastAPI Application & Routers
33
+
34
+ 1. Remove the local `create_app` factory and import the shared one:
35
+ ```python
36
+ from spaps_server_quickstart.app_factory import create_app
37
+ from spaps_server_quickstart.api.router import build_base_router
38
+ from spaps_server_quickstart.api.health import HealthRouterFactory
39
+ ```
40
+ 2. Compose routers:
41
+ ```python
42
+ settings_loader = get_settings
43
+ health_router = HealthRouterFactory(
44
+ settings_loader=settings_loader,
45
+ session_dependency=db_resources.session_dependency,
46
+ extra_metrics_provider=custom_metrics,
47
+ ).create_router()
48
+
49
+ api_router = build_base_router(
50
+ health_router,
51
+ (practitioner_router, {"prefix": "/v1", "tags": ["practitioner"]}),
52
+ )
53
+
54
+ app = create_app(
55
+ settings_loader=settings_loader,
56
+ api_router=api_router,
57
+ enable_spaps_auth=True,
58
+ auth_exempt_paths={"/open-metrics"},
59
+ )
60
+ ```
61
+ 3. Delete redundant local modules (auth, middleware, logging) once replaced.
62
+
63
+ ## 4. Database Integration
64
+
65
+ 1. Instantiate shared DB resources in a new `core/db.py` or similar:
66
+ ```python
67
+ from spaps_server_quickstart.db import DatabaseResources
68
+
69
+ db_resources = DatabaseResources(get_settings())
70
+ get_db_session = db_resources.session_dependency
71
+ ```
72
+ 2. Update dependencies in API modules (`Depends(get_db_session)`).
73
+ 3. Ensure Alembic scripts reuse the shared naming validators if applicable.
74
+
75
+ ## 5. Celery & Tasks
76
+
77
+ 1. Replace the local `Celery` bootstrap with:
78
+ ```python
79
+ from spaps_server_quickstart.tasks import create_celery_app
80
+
81
+ celery_app = create_celery_app(get_settings(), task_modules=["htma_server.tasks"])
82
+ ```
83
+ 2. Update shared tasks (`build_ping_task`, `build_notification_task`) or keep service-specific overrides as needed.
84
+
85
+ ## 6. Test & Validate
86
+
87
+ 1. Run unit/integration tests: `poetry run pytest`, `poetry run ruff`, `poetry run mypy`.
88
+ 2. Run the root `npm run prepush` to cover shared checks.
89
+ 3. Smoke test FastAPI and Celery locally if the service has start scripts.
90
+
91
+ ## 7. Cleanup & Review
92
+
93
+ 1. Remove unused files (duplicate middleware/auth/logging) and update service README docs to reference the shared package.
94
+ 2. Ensure CI passes and request review. Highlight the dependency bump and key refactors in the PR summary.
95
+
96
+ ## Appendix: Checklist
97
+
98
+ - [ ] `pyproject.toml` dependency updated and installed.
99
+ - [ ] Settings subclass uses `create_settings_loader`.
100
+ - [ ] FastAPI app uses shared `create_app` and router helpers.
101
+ - [ ] Database dependencies go through `DatabaseResources`.
102
+ - [ ] Celery uses `create_celery_app` with correct task module.
103
+ - [ ] Tests + prepush suite green.
104
+ - [ ] Redundant local scaffolding removed.
@@ -0,0 +1,82 @@
1
+ # Upgrading Downstream Services
2
+
3
+ When `spaps-server-quickstart` publishes new releases, dependent services (e.g.
4
+ `htma_server`, `ingredient_server`) need a predictable upgrade cadence. Follow this
5
+ checklist whenever we cut a release or adopt a newer version downstream.
6
+
7
+ ## For the Quickstart Maintainer (Publishing a Release)
8
+
9
+ 1. **Triage changes** – confirm whether the release is a patch, minor, or major bump.
10
+ - Patch (x.y.Z) for bug fixes and strictly backwards-compatible tweaks.
11
+ - Minor (x.Y.0) for new features that keep existing APIs stable.
12
+ - Major (X.0.0) for breaking changes; document migration steps clearly.
13
+ 2. **Update metadata**
14
+ - Bump `version` in `pyproject.toml`.
15
+ - Add release notes to `CHANGELOG.md` (include migration guidance for non-trivial upgrades).
16
+ 3. **Run validation locally**
17
+ - `python3 -m pip install -e '.[dev]'`
18
+ - `python3 -m pytest -q`
19
+ - `python3 -m ruff check src tests`
20
+ - `python3 -m mypy src`
21
+ 4. **Publish the package**
22
+ - `npm run build:python-client` is **not** required here; instead run:
23
+ ```bash
24
+ cd packages/python-server-quickstart
25
+ python -m build
26
+ python -m twine upload dist/*
27
+ ```
28
+ - If the package is private, upload to the internal index configured for SPAPS.
29
+ 5. **Announce the release**
30
+ - Share the version, changelog highlights, and any upgrade notes in the engineering
31
+ channel or release tracker.
32
+
33
+ ## For Downstream Services (Consuming a Release)
34
+
35
+ 1. **Update dependencies**
36
+ - In the service `pyproject.toml`, bump the `spaps-server-quickstart` requirement.
37
+ - Run `poetry update spaps-server-quickstart` (or `pip-compile` if using pip-tools).
38
+ 2. **Re-install local environment**
39
+ - `poetry install` (or `python3 -m pip install -e '.[dev]'`) to ensure the new version +
40
+ transitive deps are in the virtualenv.
41
+ 3. **Run the validation stack**
42
+ - `npm run prepush` from repo root (covers lint, typecheck, pytest, docs health).
43
+ Minimum checks:
44
+ ```bash
45
+ poetry run pytest
46
+ poetry run ruff check src tests
47
+ poetry run mypy src
48
+ poetry run python - <<'PY'
49
+ from spaps_server_quickstart.db import DatabaseResources
50
+ from <service>.core.settings import get_settings
51
+
52
+ resources = DatabaseResources(get_settings())
53
+ assert resources.get_session_factory()
54
+ PY
55
+ ```
56
+ - If the service uses Docker images, rebuild them locally to catch runtime regressions.
57
+ 4. **Exercise lifecycles**
58
+ - Confirm the FastAPI app starts and shuts down cleanly (`uvicorn`, `pytest` with `TestClient`).
59
+ - Verify Celery workers boot and call `create_celery_app(settings, task_modules=["<service>.tasks"])`.
60
+ 5. **Merge and deploy**
61
+ - Once CI is green, merge the dependency bump PR.
62
+ - Roll out through the standard deployment pipeline (staging → production) while watching
63
+ health checks. The shared `HealthRouterFactory` will surface database readiness issues.
64
+
65
+ ## Handling Breaking Changes
66
+
67
+ - **Major releases** should ship with migration utilities or example diffs in
68
+ `docs/UPGRADING.md`.
69
+ - If removing or renaming APIs, deprecate in one release cycle first (log a warning),
70
+ then remove in the next major version.
71
+ - Add integration tests in both the quickstart package and dependent services to guard
72
+ behaviour that might regress.
73
+
74
+ ## Version Pinning Guidelines
75
+
76
+ - Each service should pin `spaps-server-quickstart` to a compatible minor range,
77
+ e.g. `^0.2.0`.
78
+ - Avoid `*` or wide specifiers. This prevents surprise upgrades when publishing other packages.
79
+ - For hotfixes, release a patch version and bump immediately downstream.
80
+
81
+ By following this flow, the quickstart can evolve confidently while keeping HTMA, Ingredient,
82
+ and future services stable.
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.24.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "spaps-server-quickstart"
7
+ version = "0.0.1"
8
+ description = "Shared FastAPI/Celery scaffolding for Sweet Potato service backends."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "Proprietary" }
12
+ authors = [
13
+ { name = "Sweet Potato Team", email = "engineering@sweetpotato.dev" }
14
+ ]
15
+ keywords = ["sweet-potato", "fastapi", "celery", "quickstart", "spaps"]
16
+ dependencies = [
17
+ "fastapi>=0.115.0,<0.119.0",
18
+ "sqlalchemy>=2.0.32,<3.0",
19
+ "asyncpg>=0.30.0,<0.31.0",
20
+ "pydantic>=2.8.0,<3.0",
21
+ "pydantic-settings>=2.3.0,<3.0",
22
+ "structlog>=24.1.0,<26.0",
23
+ "alembic>=1.13.1,<2.0",
24
+ "celery>=5.4.0,<6.0",
25
+ "redis>=5.0.0,<6.0",
26
+ "uvicorn>=0.29.0,<0.38.0",
27
+ "httpx>=0.27.0,<0.29.0",
28
+ "tenacity>=8.3.0,<9.0",
29
+ "spaps>=0.1.2",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=8.3.0,<9.0",
35
+ "pytest-asyncio>=0.23.0,<0.24.0",
36
+ "pytest-cov>=5.0.0,<6.0",
37
+ "mypy>=1.10.0,<2.0",
38
+ "ruff>=0.5.5,<1.0",
39
+ "anyio>=4.4.0,<5.0",
40
+ ]
41
+
42
+ [project.urls]
43
+ Repository = "https://github.com/sweet-potato/spaps"
44
+
45
+ [tool.hatch.build.targets.wheel]
46
+ packages = ["src/spaps_server_quickstart"]
47
+
48
+ [tool.pytest.ini_options]
49
+ asyncio_mode = "auto"
50
+ addopts = "--cov=spaps_server_quickstart --cov-report=term-missing"
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ line-length = 100
55
+ target-version = "py310"
56
+ src = ["src"]
57
+
58
+ [tool.mypy]
59
+ python_version = "3.10"
60
+ packages = ["spaps_server_quickstart"]
61
+ strict_optional = true
62
+ ignore_missing_imports = true
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
5
+
6
+ echo "==> Running test suite"
7
+ PYTHONPATH="$PROJECT_ROOT/src" python3 -m pytest -q
8
+
9
+ echo "==> Linting"
10
+ python3 -m ruff check "$PROJECT_ROOT/src" "$PROJECT_ROOT/tests"
11
+
12
+ echo "==> Type checking"
13
+ python3 -m mypy "$PROJECT_ROOT/src"
14
+
15
+ echo "==> Building distribution"
16
+ cd "$PROJECT_ROOT"
17
+ rm -rf dist
18
+ python3 -m build
19
+
20
+ echo "==> Uploading via twine"
21
+ python3 -m twine upload dist/*
22
+
23
+ echo "Release complete."
@@ -0,0 +1,63 @@
1
+ """
2
+ Shared service scaffolding for Sweet Potato backend applications.
3
+
4
+ The package gathers reusable FastAPI, Celery, settings, database, logging, and
5
+ authentication helpers that individual services (HTMA, Ingredient, etc.) can consume.
6
+ """
7
+
8
+ from .alembic import allowed_domains, collect_directory_errors, ensure_known_domain, slugify_title, validate_migration_filename
9
+ from .app_factory import create_app
10
+ from .auth import (
11
+ AuthenticationError,
12
+ AuthenticatedUser,
13
+ SpapsAuthMiddleware,
14
+ SpapsAuthService,
15
+ build_spaps_auth_service,
16
+ )
17
+ from .api.health import HealthRouterFactory
18
+ from .api.router import build_base_router
19
+ from .db import (
20
+ AlembicMigrationRunner,
21
+ DatabaseResources,
22
+ create_async_sessionmaker,
23
+ create_migration_runner,
24
+ session_dependency_factory,
25
+ )
26
+ from .logging import configure_logging
27
+ from .middleware import RequestLoggingMiddleware
28
+ from .schemas import HealthResponse
29
+ from .settings import BaseServiceSettings, create_settings_loader, get_settings
30
+ from .tasks import create_celery_app, build_notification_task, build_ping_task
31
+
32
+ __version__ = "0.0.1"
33
+
34
+ __all__ = [
35
+ "create_app",
36
+ "BaseServiceSettings",
37
+ "create_settings_loader",
38
+ "get_settings",
39
+ "configure_logging",
40
+ "RequestLoggingMiddleware",
41
+ "AuthenticationError",
42
+ "AuthenticatedUser",
43
+ "SpapsAuthService",
44
+ "SpapsAuthMiddleware",
45
+ "build_spaps_auth_service",
46
+ "HealthRouterFactory",
47
+ "HealthResponse",
48
+ "build_base_router",
49
+ "DatabaseResources",
50
+ "create_async_sessionmaker",
51
+ "session_dependency_factory",
52
+ "AlembicMigrationRunner",
53
+ "create_migration_runner",
54
+ "create_celery_app",
55
+ "build_ping_task",
56
+ "build_notification_task",
57
+ "validate_migration_filename",
58
+ "collect_directory_errors",
59
+ "ensure_known_domain",
60
+ "allowed_domains",
61
+ "slugify_title",
62
+ "__version__",
63
+ ]
@@ -0,0 +1,21 @@
1
+ """
2
+ Alembic helpers for naming conventions and migration utilities.
3
+ """
4
+
5
+ from .naming import (
6
+ allowed_domains,
7
+ build_revision_message,
8
+ collect_directory_errors,
9
+ ensure_known_domain,
10
+ slugify_title,
11
+ validate_migration_filename,
12
+ )
13
+
14
+ __all__ = [
15
+ "validate_migration_filename",
16
+ "collect_directory_errors",
17
+ "ensure_known_domain",
18
+ "allowed_domains",
19
+ "slugify_title",
20
+ "build_revision_message",
21
+ ]