tempest-fastapi-sdk 0.89.0__tar.gz → 0.91.0__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.
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/CHANGELOG.md +81 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/CLAUDE.md +16 -6
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/PKG-INFO +12 -12
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/README.md +11 -11
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/architecture.en.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/architecture.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/installation.en.md +5 -3
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/installation.md +5 -3
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/api.en.md +1 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/api.md +1 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/business-rules.en.md +0 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/business-rules.md +0 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/domain.en.md +2 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/domain.md +2 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/flows.en.md +12 -5
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/flows.md +12 -5
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/index.en.md +3 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/index.md +3 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/migration.en.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/migration.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/admin.en.md +13 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/admin.md +13 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/audit-trail.en.md +8 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/audit-trail.md +8 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/auth-flow.en.md +3 -3
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/auth-flow.md +3 -3
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/br-helpers.en.md +19 -9
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/br-helpers.md +19 -9
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/cache.en.md +12 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/cache.md +12 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/cli.en.md +22 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/cli.md +21 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/downloads.md +2 -2
- tempest_fastapi_sdk-0.91.0/docs/recipes/file-store.en.md +138 -0
- tempest_fastapi_sdk-0.91.0/docs/recipes/file-store.md +135 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/http-client.en.md +23 -5
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/http-client.md +23 -5
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/http.en.md +33 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/http.md +33 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/idempotency.en.md +17 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/idempotency.md +17 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/index.en.md +14 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/index.md +14 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/logging.en.md +1 -30
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/logging.md +1 -30
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/metrics.en.md +14 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/metrics.md +14 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/mfa.en.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/mfa.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/multi-tenant.en.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/multi-tenant.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/offline-sync.en.md +9 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/offline-sync.md +9 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/queue-tasks.en.md +20 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/queue-tasks.md +20 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/security.en.md +23 -8
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/security.md +23 -8
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/sessions.en.md +18 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/sessions.md +18 -1
- tempest_fastapi_sdk-0.91.0/docs/recipes/sse.en.md +390 -0
- tempest_fastapi_sdk-0.91.0/docs/recipes/sse.md +390 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/storage.en.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/storage.md +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/testing.en.md +14 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/testing.md +14 -4
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/typing.en.md +29 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/typing.md +29 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/utilities.en.md +3 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/utilities.md +3 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/webpush.en.md +32 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/webpush.md +32 -2
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/websocket.en.md +15 -8
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/websocket.md +15 -8
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/reference.md +2 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/roadmap.en.md +22 -86
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/roadmap.md +22 -86
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/tutorial.en.md +22 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/tutorial.md +22 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/mkdocs.yml +2 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/pyproject.toml +1 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/__init__.py +5 -1
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/dependencies/auth.py +38 -7
- tempest_fastapi_sdk-0.91.0/tempest_fastapi_sdk/sse/__init__.py +23 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sse/broker.py +53 -2
- tempest_fastapi_sdk-0.91.0/tempest_fastapi_sdk/sse/event_stream.py +368 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/__init__.py +2 -0
- tempest_fastapi_sdk-0.91.0/tempest_fastapi_sdk/utils/file_store.py +440 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/upload.py +33 -15
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_jwt_dependency.py +75 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/sse/test_broker.py +35 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/sse/test_event_stream.py +98 -0
- tempest_fastapi_sdk-0.91.0/tests/utils/test_file_store.py +272 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/uv.lock +1 -1
- tempest_fastapi_sdk-0.89.0/docs/recipes/sse.en.md +0 -225
- tempest_fastapi_sdk-0.89.0/docs/recipes/sse.md +0 -225
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/sse/__init__.py +0 -15
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/sse/event_stream.py +0 -205
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/.github/workflows/ci.yml +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/.github/workflows/docs.yml +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/.gitignore +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/.python-version +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/Makefile +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/changelog.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/changelog.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/contributing.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/contributing.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/index.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/index.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/index.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/index.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/database.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/database.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/deploy-safety.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/deploy-safety.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/downloads.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/email.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/email.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/feature-flags.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/feature-flags.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/fields.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/fields.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/observability.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/observability.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/outbox.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/outbox.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/realtime.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/realtime.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/refresh-tokens.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/refresh-tokens.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/stored-files.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/stored-files.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/uploads.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/uploads.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/vision.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/recipes/vision.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/reference.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/ssr.en.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/ssr.md +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/mkdocs_hooks/llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/scripts/extract_recipe.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/actions.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/auth.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/config.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/discovery.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/forms.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/session.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/site.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/static/admin.css +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/detail.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/form.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/list.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/logs.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/templates/mfa.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/admin/theme.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/graceful.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/server.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/static.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/tracing.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/guards.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/locale.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/activation.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/auth/token_delivery.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cache/invalidation.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/Dockerfile.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/dockerignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/resources.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/config.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/db.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/main.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/new.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/secrets.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/src_layers.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/cli/user.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/controllers/base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/core/context.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/core/enums.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/core/logging.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/core/typed.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/audit.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/backup.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/connection.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/mixins.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/outbox.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/repository.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/slow_query.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/tenant.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/user_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/user_recovery_code_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/user_refresh_token_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/user_token_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/db/webpush_subscription_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/i18n.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/flags/backends.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/flags/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/flags/service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/py.typed +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/services/base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/services/file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/settings/base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/settings/mixins.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/ssr/_static/htmx.min.js +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/ssr/assets.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/ssr/page.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/ssr/response.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/storage/minio_client.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/testing/database.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/data/br_locations.json +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/download.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/email.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/fields.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/locations.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/log.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/password.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/utils/totp.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/vision/mapping.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/vision/schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/webpush/router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/webpush/service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_actions.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_auth.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_discovery.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_forms.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_logs_nav.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_rich_filters.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_site.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_theme.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_upload_field.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/admin/test_user_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_body_size.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_cookies.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_cors.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_csrf.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_dependencies_auth.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_graceful.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_handlers.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_health_router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_idempotency.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_logs_router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_oauth.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_prometheus.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_rate_limit_extras.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_request_id_middleware.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_role_dependency.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_server.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_static.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/api/test_webhooks_rsa.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_cookie_delivery.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_guards.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_locale.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_refresh.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_refresh_db.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/auth/test_service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cache/test_decorator.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cache/test_invalidation.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cache/test_redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_config.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_db.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_db_seed.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_lint_strictness.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_main.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_secrets.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/cli/test_user.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/conftest.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/controllers/test_base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/core/test_context.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/core/test_enums.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/core/test_logging.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/core/test_typed.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_audit.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_backup.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_bulk_ops.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_connection.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_migrations.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_model.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_outbox.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_repository.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_safe_upgrade.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_slow_query.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/db/test_tenant.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/exceptions/test_exceptions.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/exceptions/test_i18n.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/flags/test_flags.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/queue/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/test_base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/test_cursor_pagination.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/test_link_headers.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/test_pagination.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/schemas/test_response.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/services/test_base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/services/test_file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/sessions/test_sessions.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/settings/test_base.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/settings/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/ssr/test_integration.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/ssr/test_page.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/ssr/test_response.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/storage/test_minio_client.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/tasks/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/tasks/test_scheduler.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/testing/test_database.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_client_ip.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_datetime.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_dict.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_download.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_email.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_fields.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_http_client.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_jwt.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_lazy_extras.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_locations.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_log.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_metrics.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_password.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_regex.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_throttle.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/utils/test_upload.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/vision/test_vision.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/webpush/test_dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/webpush/test_router.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/webpush/test_schemas.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/webpush/test_service.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/tests/websockets/test_hub_and_router.py +0 -0
|
@@ -5,6 +5,87 @@ All notable changes to **tempest-fastapi-sdk** are listed below.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.91.0] — 2026-07-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **SSE backpressure — bounded queue + overflow policy.**
|
|
13
|
+
`EventStream` (and `SSEBroker`-created streams) now cap the buffered
|
|
14
|
+
events at `max_queue` (default `1000`) instead of growing without
|
|
15
|
+
limit when a client stalls. When the buffer fills, `overflow` decides
|
|
16
|
+
what gives:
|
|
17
|
+
- `"drop_oldest"` (default) — evict the stalest event, keep the
|
|
18
|
+
freshest data.
|
|
19
|
+
- `"drop_newest"` — discard the incoming event, keep the backlog.
|
|
20
|
+
- `"block"` — apply real backpressure (the producer waits for a slot).
|
|
21
|
+
`EventStream.dropped_events` counts events lost to overflow for
|
|
22
|
+
metrics / logs. `max_queue=0` restores the pre-0.91 unbounded
|
|
23
|
+
behavior. The `close()` sentinel is never dropped or blocked, so a
|
|
24
|
+
stream can always terminate. `SSEBroker(max_queue=..., overflow=...)`
|
|
25
|
+
applies the same policy to every stream it opens.
|
|
26
|
+
- **SSE lifecycle helpers — no more hand-rolled `try/finally`.**
|
|
27
|
+
- `sse_response(..., on_disconnect=...)` runs a cleanup callback
|
|
28
|
+
(awaited if a coroutine) when the client disconnects or the stream
|
|
29
|
+
ends — the one place guaranteed to fire — so a bound producer task
|
|
30
|
+
is cancelled or a channel unregistered without boilerplate.
|
|
31
|
+
- `EventStream.response(*, on_disconnect=..., status_code=...,
|
|
32
|
+
headers=...)` wraps `stream()` in an SSE response in one call.
|
|
33
|
+
- `SSEBroker.response(channel, ...)` bundles the whole per-connection
|
|
34
|
+
lifecycle: `register` + `sse_response` + `unregister`-on-disconnect.
|
|
35
|
+
This removes the leak-prone manual wrapper the recipe used to need.
|
|
36
|
+
- **JWT via query string for cookieless clients.**
|
|
37
|
+
`make_bearer_token_dependency` and `make_jwt_user_dependency` gained a
|
|
38
|
+
`query_param` argument (e.g. `query_param="access_token"`). Token
|
|
39
|
+
lookup order becomes header → cookie → query string. This unblocks
|
|
40
|
+
browser `EventSource` (SSE), whose constructor accepts neither headers
|
|
41
|
+
nor a body. Documented with a security warning: use short-lived access
|
|
42
|
+
tokens only, over TLS, and scrub the value from access logs. Prefer a
|
|
43
|
+
session cookie (`withCredentials`) whenever the client shares the
|
|
44
|
+
API's origin.
|
|
45
|
+
- **`OverflowPolicy`** is exported from `tempest_fastapi_sdk.sse` and the
|
|
46
|
+
package root.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- `tempest_fastapi_sdk/sse/__init__.py` re-exports now use the explicit
|
|
51
|
+
`X as X` alias form required by the repo's re-export convention (was a
|
|
52
|
+
structural defect flagged by strict type-checkers).
|
|
53
|
+
|
|
54
|
+
## [0.90.0] — 2026-07-04
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **Unified file store (`FileStoreUtils`).** A single facade over the
|
|
59
|
+
three pieces a service usually wires by hand — `UploadUtils`
|
|
60
|
+
(validate + persist), `DownloadUtils` (serve bytes through the API)
|
|
61
|
+
and the presigned-URL helpers of `AsyncMinIOClient` — behind one
|
|
62
|
+
object with one configuration, targeting one storage backend.
|
|
63
|
+
- The backend is picked once from `source`: a directory path for
|
|
64
|
+
local disk (`[upload]` extra), or an `AsyncMinIOClient` for
|
|
65
|
+
MinIO/S3 (`[minio]` extra).
|
|
66
|
+
- Convenience surface: `save` / `replace` / `delete` / `exists`,
|
|
67
|
+
`download` / `file_response` / `stream` / `resolve`, `validate`,
|
|
68
|
+
and `presigned_get_url` / `presigned_put_url` (the latter return
|
|
69
|
+
`None` on the local backend, keeping the call site uniform).
|
|
70
|
+
- Escape hatches for the internal pieces: `uploader`, `downloader`,
|
|
71
|
+
`backend` and `client`.
|
|
72
|
+
- A single `UploadStorage` backend is built and shared with the
|
|
73
|
+
upload half; on MinIO the same client instance is reused by the
|
|
74
|
+
download half, so the connection pool is shared, not duplicated.
|
|
75
|
+
- **`UploadUtils` accepts an injected backend.** New keyword-only
|
|
76
|
+
`backend: UploadStorage | None` bypasses the `source`-based backend
|
|
77
|
+
selection, letting `FileStoreUtils` build one backend and share it.
|
|
78
|
+
`source` is now optional when `backend` is given; passing neither
|
|
79
|
+
raises `ValueError`. The `[upload]` extra is only required when the
|
|
80
|
+
local backend is actually selected (MinIO-only use no longer needs
|
|
81
|
+
`aiofiles`).
|
|
82
|
+
|
|
83
|
+
### Docs
|
|
84
|
+
|
|
85
|
+
- New bilingual recipe **File store (unificado) / Unified file store**
|
|
86
|
+
(`docs/recipes/file-store.md` + `.en.md`) and an API-reference stub
|
|
87
|
+
for `FileStoreUtils` (plus `DownloadUtils`).
|
|
88
|
+
|
|
8
89
|
## [0.89.0] — 2026-07-04
|
|
9
90
|
|
|
10
91
|
### Added
|
|
@@ -55,7 +55,9 @@ without the docs being green.
|
|
|
55
55
|
|
|
56
56
|
The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
57
57
|
|
|
58
|
-
- **Auth** — JWT/bearer/role/permission/X-Token deps
|
|
58
|
+
- **Auth** — JWT/bearer/role/permission/X-Token deps (JWT deps
|
|
59
|
+
read the token from header → cookie → query string via
|
|
60
|
+
`query_param=`, for cookieless `EventSource`/SSE clients), full
|
|
59
61
|
bundled flow (`UserAuthService` + `make_auth_router` covering
|
|
60
62
|
signup/activate/login/password-reset), `BaseUserModel` +
|
|
61
63
|
`BaseUserTokenModel`, OAuth2/OIDC providers
|
|
@@ -88,9 +90,14 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
88
90
|
- **Pagination** — offset + cursor.
|
|
89
91
|
- **Settings mixins** — every `*Settings` carries
|
|
90
92
|
`title`/`description`/`examples` on every field.
|
|
91
|
-
- **SSE** — `EventStream
|
|
92
|
-
`
|
|
93
|
-
|
|
93
|
+
- **SSE** — `EventStream` (bounded queue + `overflow` backpressure —
|
|
94
|
+
`drop_oldest`/`drop_newest`/`block`, `dropped_events` counter,
|
|
95
|
+
`max_queue=0` to disable), `ServerSentEvent`, `sse_response`
|
|
96
|
+
(`on_disconnect=` cleanup), `EventStream.response`, and `SSEBroker`
|
|
97
|
+
(per-channel fan-out; `SSEBroker.response(channel)` bundles
|
|
98
|
+
register + response + unregister-on-disconnect; in-memory
|
|
99
|
+
single-process, or multi-worker via an injected Redis pub/sub bridge
|
|
100
|
+
— same call site).
|
|
94
101
|
- **Throttle** — `AttemptThrottle` (any `ThrottleBackend`, e.g.
|
|
95
102
|
`redis.asyncio.Redis`; no in-memory backend bundled).
|
|
96
103
|
- **Base CRUD layers** — `BaseService[Repo, Resp, UpdateT]` and
|
|
@@ -123,8 +130,11 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
123
130
|
`tempestweb` imported lazily so `import tempest_fastapi_sdk` never
|
|
124
131
|
needs the extra.
|
|
125
132
|
- **Upload** — `UploadUtils` with pluggable backends
|
|
126
|
-
(`LocalUploadStorage`, `MinIOUploadStorage
|
|
127
|
-
presigned URLs
|
|
133
|
+
(`LocalUploadStorage`, `MinIOUploadStorage`, opt-in injected via
|
|
134
|
+
`backend=`), download helpers, presigned URLs, plus `FileStoreUtils`
|
|
135
|
+
— a unified facade bundling upload + download + presign over one
|
|
136
|
+
shared backend (`uploader`/`downloader`/`backend`/`client` escape
|
|
137
|
+
hatches).
|
|
128
138
|
- **MinIO / S3** — `AsyncMinIOClient` via `[minio]` extra
|
|
129
139
|
(bucket lifecycle, object I/O, streaming download, presigned
|
|
130
140
|
URLs).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempest-fastapi-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.91.0
|
|
4
4
|
Summary: Shared FastAPI building blocks: base schemas, ORM model, async repository, exceptions, pagination and settings — the conventions used across Tempest projects.
|
|
5
5
|
Project-URL: Homepage, https://github.com/mauriciobenjamin700/tempest-fastapi-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/mauriciobenjamin700/tempest-fastapi-sdk
|
|
@@ -119,7 +119,7 @@ Description-Content-Type: text/markdown
|
|
|
119
119
|
|
|
120
120
|
> 💡 `uv run mkdocs serve` (ou `make docs-serve`) é só para preview local — em produção use as URLs do GitHub Pages acima. / For local preview only — in production use the GitHub Pages URLs above.
|
|
121
121
|
|
|
122
|
-
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
122
|
+
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `FileStoreUtils`, `MetricsUtils`, `LogUtils`).
|
|
123
123
|
|
|
124
124
|
The goal is to start every new backend with the same opinionated foundation already in place — no copy-pasting `BaseModel`, no rewriting the same CRUD repository, no re-inventing the exception envelope.
|
|
125
125
|
|
|
@@ -200,7 +200,7 @@ Via `pyproject.toml`:
|
|
|
200
200
|
|
|
201
201
|
```toml
|
|
202
202
|
dependencies = [
|
|
203
|
-
"tempest-fastapi-sdk>=0.
|
|
203
|
+
"tempest-fastapi-sdk>=0.91.0",
|
|
204
204
|
]
|
|
205
205
|
```
|
|
206
206
|
|
|
@@ -258,7 +258,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
258
258
|
| `tempest_fastapi_sdk.services` | `BaseService` |
|
|
259
259
|
| `tempest_fastapi_sdk.core` | `configure_logging`, `JSONFormatter`, `get_request_id`/`set_request_id`/`clear_request_id`, `request_id_ctx`, `BaseStrEnum`, `BaseIntEnum`, `strict_types`/`typed`/`require_annotations` |
|
|
260
260
|
| `tempest_fastapi_sdk.admin` *(extra: `[admin]`)* | `AdminSite`, `AdminModel`, `make_admin_router`, `AdminAuthBackend`, `UserModelAuthBackend`, `AdminAuthError` |
|
|
261
|
-
| `tempest_fastapi_sdk.sse` | `EventStream
|
|
261
|
+
| `tempest_fastapi_sdk.sse` | `EventStream` (bounded queue + `overflow` backpressure), `SSEBroker` (multi-worker fan-out via Redis, `.response()` lifecycle helper), `ServerSentEvent`, `sse_response` (`on_disconnect=` cleanup) |
|
|
262
262
|
| `tempest_fastapi_sdk.cache` *(extra: `[cache]`)* | `AsyncRedisManager`, `cached` (with `namespace` / `tags`), `CacheInvalidator`, `namespace_registry_key`, `tag_registry_key` |
|
|
263
263
|
| `tempest_fastapi_sdk.flags` | `FeatureFlags`, `FeatureFlagBackend`, `MemoryFeatureFlagBackend`, `EnvFeatureFlagBackend`, `RedisFeatureFlagBackend`, `CompositeFeatureFlagBackend`, `make_flag_dependency`, `coerce_flag` |
|
|
264
264
|
| `tempest_fastapi_sdk.webpush` *(extra: `[webpush]`)* | `WebPushDispatcher`, `WebPushSubscriptionService`, `make_web_push_router`, `WebPushError`, `WebPushGoneError`, `WebPushSubscriptionSchema`, `WebPushKeysSchema`, `WebPushPayloadSchema` |
|
|
@@ -269,7 +269,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
269
269
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
270
270
|
| `tempest_fastapi_sdk.vision` *(extra: `[vision]`)* | `Detector`, `Classifier`, `Segmenter` (ONNX, lazy), `DetectionSchema`/`ClassificationSchema`/`SegmentationSchema`/`BoundingBoxSchema`/`ClassProbabilitySchema`, `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas` |
|
|
271
271
|
| `tempest_fastapi_sdk.ssr` *(extra: `[ssr]`)* | `Page` (typed component base), `html_response` (widget tree → `HTMLResponse`, full document or HTMX fragment), `make_htmx_router` (serves bundled HTMX locally, no CDN) |
|
|
272
|
-
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
272
|
+
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `FileStoreUtils` — unified upload+download+presign facade *(extra: `[upload]` local / `[minio]` MinIO)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
273
273
|
| `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
|
|
274
274
|
|
|
275
275
|
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks`, `tempest_fastapi_sdk.vision` and `tempest_fastapi_sdk.ssr` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
@@ -1050,7 +1050,7 @@ tokens = JWTUtils(
|
|
|
1050
1050
|
|
|
1051
1051
|
#### Signup
|
|
1052
1052
|
|
|
1053
|
-
Reuse the `UserService.
|
|
1053
|
+
Reuse the `UserService.signup` defined in the tutorial — it already hashes the password.
|
|
1054
1054
|
|
|
1055
1055
|
#### Login
|
|
1056
1056
|
|
|
@@ -2445,7 +2445,7 @@ import asyncio
|
|
|
2445
2445
|
|
|
2446
2446
|
from fastapi import APIRouter
|
|
2447
2447
|
|
|
2448
|
-
from tempest_fastapi_sdk import EventStream
|
|
2448
|
+
from tempest_fastapi_sdk import EventStream
|
|
2449
2449
|
|
|
2450
2450
|
router = APIRouter()
|
|
2451
2451
|
|
|
@@ -2460,8 +2460,9 @@ async def events() -> "StreamingResponse": # forward-declared by Starlette
|
|
|
2460
2460
|
await asyncio.sleep(1)
|
|
2461
2461
|
await stream.close()
|
|
2462
2462
|
|
|
2463
|
-
asyncio.create_task(producer())
|
|
2464
|
-
|
|
2463
|
+
task = asyncio.create_task(producer())
|
|
2464
|
+
# on_disconnect cancels the producer when the client drops — no leak.
|
|
2465
|
+
return stream.response(on_disconnect=task.cancel)
|
|
2465
2466
|
```
|
|
2466
2467
|
|
|
2467
2468
|
Browser side:
|
|
@@ -2473,6 +2474,8 @@ es.addEventListener("counter", (e) => console.log("got", JSON.parse(e.data)));
|
|
|
2473
2474
|
|
|
2474
2475
|
`heartbeat_seconds` emits a `: keepalive` SSE comment when idle so load-balancers don't close long-lived connections. `ServerSentEvent.data` accepts strings, bytes or any JSON-serializable Python object — non-strings are JSON-encoded automatically. Pass `retry=` to hint the browser at the reconnect delay (milliseconds).
|
|
2475
2476
|
|
|
2477
|
+
The queue is **bounded** (`max_queue`, default `1000`): a slow client can't grow memory without limit. `overflow` picks the eviction policy — `"drop_oldest"` (default), `"drop_newest"`, or `"block"` (real backpressure); `EventStream.dropped_events` counts the discards. For broadcast, `SSEBroker.response(channel)` bundles `register` + `sse_response` + `unregister`-on-disconnect in one call. Authenticating an `EventSource` (which can't send an `Authorization` header): prefer a session cookie (`make_jwt_user_dependency(..., cookie_name="access_token")` + `withCredentials`); for cookieless clients pass a short-lived access token in the query string with `query_param="access_token"` (over TLS, scrubbed from logs). See the [SSE recipe](https://mauriciobenjamin700.github.io/tempest-fastapi-sdk/recipes/sse/) for the full guide.
|
|
2478
|
+
|
|
2476
2479
|
### Web Push notifications recipe
|
|
2477
2480
|
|
|
2478
2481
|
`WebPushDispatcher` wraps the synchronous `pywebpush` library in `asyncio.to_thread` and surfaces the two errors the application cares about: `WebPushGoneError` (HTTP 404/410 — delete the subscription) and `WebPushError` (everything else). Install with `[webpush]`.
|
|
@@ -4187,9 +4190,6 @@ Short version — recently shipped and what's next:
|
|
|
4187
4190
|
- **v0.31.2** — `UserAuthService` methods type `session` as
|
|
4188
4191
|
`AsyncSession` everywhere (no more `Any`).
|
|
4189
4192
|
|
|
4190
|
-
Still on the roadmap: OpenTelemetry tracing + outbox pattern
|
|
4191
|
-
for transactional events. Tracked on the docs page.
|
|
4192
|
-
|
|
4193
4193
|
---
|
|
4194
4194
|
|
|
4195
4195
|
## License
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
> 💡 `uv run mkdocs serve` (ou `make docs-serve`) é só para preview local — em produção use as URLs do GitHub Pages acima. / For local preview only — in production use the GitHub Pages URLs above.
|
|
12
12
|
|
|
13
|
-
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
13
|
+
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `FileStoreUtils`, `MetricsUtils`, `LogUtils`).
|
|
14
14
|
|
|
15
15
|
The goal is to start every new backend with the same opinionated foundation already in place — no copy-pasting `BaseModel`, no rewriting the same CRUD repository, no re-inventing the exception envelope.
|
|
16
16
|
|
|
@@ -91,7 +91,7 @@ Via `pyproject.toml`:
|
|
|
91
91
|
|
|
92
92
|
```toml
|
|
93
93
|
dependencies = [
|
|
94
|
-
"tempest-fastapi-sdk>=0.
|
|
94
|
+
"tempest-fastapi-sdk>=0.91.0",
|
|
95
95
|
]
|
|
96
96
|
```
|
|
97
97
|
|
|
@@ -149,7 +149,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
149
149
|
| `tempest_fastapi_sdk.services` | `BaseService` |
|
|
150
150
|
| `tempest_fastapi_sdk.core` | `configure_logging`, `JSONFormatter`, `get_request_id`/`set_request_id`/`clear_request_id`, `request_id_ctx`, `BaseStrEnum`, `BaseIntEnum`, `strict_types`/`typed`/`require_annotations` |
|
|
151
151
|
| `tempest_fastapi_sdk.admin` *(extra: `[admin]`)* | `AdminSite`, `AdminModel`, `make_admin_router`, `AdminAuthBackend`, `UserModelAuthBackend`, `AdminAuthError` |
|
|
152
|
-
| `tempest_fastapi_sdk.sse` | `EventStream
|
|
152
|
+
| `tempest_fastapi_sdk.sse` | `EventStream` (bounded queue + `overflow` backpressure), `SSEBroker` (multi-worker fan-out via Redis, `.response()` lifecycle helper), `ServerSentEvent`, `sse_response` (`on_disconnect=` cleanup) |
|
|
153
153
|
| `tempest_fastapi_sdk.cache` *(extra: `[cache]`)* | `AsyncRedisManager`, `cached` (with `namespace` / `tags`), `CacheInvalidator`, `namespace_registry_key`, `tag_registry_key` |
|
|
154
154
|
| `tempest_fastapi_sdk.flags` | `FeatureFlags`, `FeatureFlagBackend`, `MemoryFeatureFlagBackend`, `EnvFeatureFlagBackend`, `RedisFeatureFlagBackend`, `CompositeFeatureFlagBackend`, `make_flag_dependency`, `coerce_flag` |
|
|
155
155
|
| `tempest_fastapi_sdk.webpush` *(extra: `[webpush]`)* | `WebPushDispatcher`, `WebPushSubscriptionService`, `make_web_push_router`, `WebPushError`, `WebPushGoneError`, `WebPushSubscriptionSchema`, `WebPushKeysSchema`, `WebPushPayloadSchema` |
|
|
@@ -160,7 +160,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
160
160
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
161
161
|
| `tempest_fastapi_sdk.vision` *(extra: `[vision]`)* | `Detector`, `Classifier`, `Segmenter` (ONNX, lazy), `DetectionSchema`/`ClassificationSchema`/`SegmentationSchema`/`BoundingBoxSchema`/`ClassProbabilitySchema`, `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas` |
|
|
162
162
|
| `tempest_fastapi_sdk.ssr` *(extra: `[ssr]`)* | `Page` (typed component base), `html_response` (widget tree → `HTMLResponse`, full document or HTMX fragment), `make_htmx_router` (serves bundled HTMX locally, no CDN) |
|
|
163
|
-
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
163
|
+
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `FileStoreUtils` — unified upload+download+presign facade *(extra: `[upload]` local / `[minio]` MinIO)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
164
164
|
| `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
|
|
165
165
|
|
|
166
166
|
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks`, `tempest_fastapi_sdk.vision` and `tempest_fastapi_sdk.ssr` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
@@ -941,7 +941,7 @@ tokens = JWTUtils(
|
|
|
941
941
|
|
|
942
942
|
#### Signup
|
|
943
943
|
|
|
944
|
-
Reuse the `UserService.
|
|
944
|
+
Reuse the `UserService.signup` defined in the tutorial — it already hashes the password.
|
|
945
945
|
|
|
946
946
|
#### Login
|
|
947
947
|
|
|
@@ -2336,7 +2336,7 @@ import asyncio
|
|
|
2336
2336
|
|
|
2337
2337
|
from fastapi import APIRouter
|
|
2338
2338
|
|
|
2339
|
-
from tempest_fastapi_sdk import EventStream
|
|
2339
|
+
from tempest_fastapi_sdk import EventStream
|
|
2340
2340
|
|
|
2341
2341
|
router = APIRouter()
|
|
2342
2342
|
|
|
@@ -2351,8 +2351,9 @@ async def events() -> "StreamingResponse": # forward-declared by Starlette
|
|
|
2351
2351
|
await asyncio.sleep(1)
|
|
2352
2352
|
await stream.close()
|
|
2353
2353
|
|
|
2354
|
-
asyncio.create_task(producer())
|
|
2355
|
-
|
|
2354
|
+
task = asyncio.create_task(producer())
|
|
2355
|
+
# on_disconnect cancels the producer when the client drops — no leak.
|
|
2356
|
+
return stream.response(on_disconnect=task.cancel)
|
|
2356
2357
|
```
|
|
2357
2358
|
|
|
2358
2359
|
Browser side:
|
|
@@ -2364,6 +2365,8 @@ es.addEventListener("counter", (e) => console.log("got", JSON.parse(e.data)));
|
|
|
2364
2365
|
|
|
2365
2366
|
`heartbeat_seconds` emits a `: keepalive` SSE comment when idle so load-balancers don't close long-lived connections. `ServerSentEvent.data` accepts strings, bytes or any JSON-serializable Python object — non-strings are JSON-encoded automatically. Pass `retry=` to hint the browser at the reconnect delay (milliseconds).
|
|
2366
2367
|
|
|
2368
|
+
The queue is **bounded** (`max_queue`, default `1000`): a slow client can't grow memory without limit. `overflow` picks the eviction policy — `"drop_oldest"` (default), `"drop_newest"`, or `"block"` (real backpressure); `EventStream.dropped_events` counts the discards. For broadcast, `SSEBroker.response(channel)` bundles `register` + `sse_response` + `unregister`-on-disconnect in one call. Authenticating an `EventSource` (which can't send an `Authorization` header): prefer a session cookie (`make_jwt_user_dependency(..., cookie_name="access_token")` + `withCredentials`); for cookieless clients pass a short-lived access token in the query string with `query_param="access_token"` (over TLS, scrubbed from logs). See the [SSE recipe](https://mauriciobenjamin700.github.io/tempest-fastapi-sdk/recipes/sse/) for the full guide.
|
|
2369
|
+
|
|
2367
2370
|
### Web Push notifications recipe
|
|
2368
2371
|
|
|
2369
2372
|
`WebPushDispatcher` wraps the synchronous `pywebpush` library in `asyncio.to_thread` and surfaces the two errors the application cares about: `WebPushGoneError` (HTTP 404/410 — delete the subscription) and `WebPushError` (everything else). Install with `[webpush]`.
|
|
@@ -4078,9 +4081,6 @@ Short version — recently shipped and what's next:
|
|
|
4078
4081
|
- **v0.31.2** — `UserAuthService` methods type `session` as
|
|
4079
4082
|
`AsyncSession` everywhere (no more `Any`).
|
|
4080
4083
|
|
|
4081
|
-
Still on the roadmap: OpenTelemetry tracing + outbox pattern
|
|
4082
|
-
for transactional events. Tracked on the docs page.
|
|
4083
|
-
|
|
4084
4084
|
---
|
|
4085
4085
|
|
|
4086
4086
|
## License
|
|
@@ -213,7 +213,7 @@ class UserController(BaseController[UserService, UserResponse]):
|
|
|
213
213
|
from fastapi import Depends
|
|
214
214
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
215
215
|
|
|
216
|
-
from src.api.
|
|
216
|
+
from src.api.dependencies.resources import db
|
|
217
217
|
from src.controllers.user_controller import UserController
|
|
218
218
|
from src.db.repositories import UserRepository
|
|
219
219
|
from src.services.user_service import UserService
|
|
@@ -213,7 +213,7 @@ class UserController(BaseController[UserService, UserResponse]):
|
|
|
213
213
|
from fastapi import Depends
|
|
214
214
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
215
215
|
|
|
216
|
-
from src.api.
|
|
216
|
+
from src.api.dependencies.resources import db
|
|
217
217
|
from src.controllers.user_controller import UserController
|
|
218
218
|
from src.db.repositories import UserRepository
|
|
219
219
|
from src.services.user_service import UserService
|
|
@@ -32,7 +32,9 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
|
|
|
32
32
|
| `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA (TOTP) endpoints on the bundled auth flow |
|
|
33
33
|
| `[sqlite]` | `aiosqlite` | SQLite async driver for `sqlite+aiosqlite://` URLs (dev default) |
|
|
34
34
|
| `[postgres]` | `asyncpg` | PostgreSQL async driver for `postgresql+asyncpg://` URLs (production) |
|
|
35
|
-
| `[
|
|
35
|
+
| `[vision]` | `ort-vision-sdk` | vision helpers (`Detector`, `Classifier`, `Segmenter` + `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas`) |
|
|
36
|
+
| `[otel]` | `opentelemetry-sdk`, OTLP exporter + FastAPI/SQLAlchemy/httpx instrumentations | OpenTelemetry instrumentation via `setup_tracing` |
|
|
37
|
+
| `[all]` | everything above (includes `[vision]` and `[otel]`) | every helper |
|
|
36
38
|
|
|
37
39
|
=== "Subset (recommended)"
|
|
38
40
|
|
|
@@ -49,14 +51,14 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
|
|
|
49
51
|
=== "uv add"
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
|
-
uv add "tempest-fastapi-sdk[auth,upload,postgres]>=0.
|
|
54
|
+
uv add "tempest-fastapi-sdk[auth,upload,postgres]>=0.89.0"
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
=== "pyproject.toml"
|
|
56
58
|
|
|
57
59
|
```toml
|
|
58
60
|
dependencies = [
|
|
59
|
-
"tempest-fastapi-sdk[auth,upload,postgres]>=0.
|
|
61
|
+
"tempest-fastapi-sdk[auth,upload,postgres]>=0.89.0",
|
|
60
62
|
]
|
|
61
63
|
```
|
|
62
64
|
|
|
@@ -32,7 +32,9 @@ Os helpers mais ricos puxam dependências de terceiros que só são necessárias
|
|
|
32
32
|
| `[mfa]` | `pyotp` | `TOTPHelper` + endpoints MFA/2FA (TOTP) do fluxo bundled de auth |
|
|
33
33
|
| `[sqlite]` | `aiosqlite` | driver async SQLite para URLs `sqlite+aiosqlite://` (default de dev) |
|
|
34
34
|
| `[postgres]` | `asyncpg` | driver async PostgreSQL para URLs `postgresql+asyncpg://` (produção) |
|
|
35
|
-
| `[
|
|
35
|
+
| `[vision]` | `ort-vision-sdk` | helpers de visão (`Detector`, `Classifier`, `Segmenter` + `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas`) |
|
|
36
|
+
| `[otel]` | `opentelemetry-sdk`, exporter OTLP + instrumentações FastAPI/SQLAlchemy/httpx | instrumentação OpenTelemetry via `setup_tracing` |
|
|
37
|
+
| `[all]` | tudo acima (inclui `[vision]` e `[otel]`) | todos os helpers |
|
|
36
38
|
|
|
37
39
|
=== "Subconjunto (recomendado)"
|
|
38
40
|
|
|
@@ -49,14 +51,14 @@ Os helpers mais ricos puxam dependências de terceiros que só são necessárias
|
|
|
49
51
|
=== "uv add"
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
|
-
uv add "tempest-fastapi-sdk[auth,upload,postgres]>=0.
|
|
54
|
+
uv add "tempest-fastapi-sdk[auth,upload,postgres]>=0.89.0"
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
=== "pyproject.toml"
|
|
56
58
|
|
|
57
59
|
```toml
|
|
58
60
|
dependencies = [
|
|
59
|
-
"tempest-fastapi-sdk[auth,upload,postgres]>=0.
|
|
61
|
+
"tempest-fastapi-sdk[auth,upload,postgres]>=0.89.0",
|
|
60
62
|
]
|
|
61
63
|
```
|
|
62
64
|
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/api.en.md
RENAMED
|
@@ -7,6 +7,7 @@ The full REST API of the marketplace in a single table, ready to paste into the
|
|
|
7
7
|
- **Idem**: ✅ = accepts `Idempotency-Key` (cached by `IdempotencyMiddleware`).
|
|
8
8
|
- **Pagination**: cursor by default; offset where explicitly noted.
|
|
9
9
|
- **Errors**: every error follows the SDK envelope `{detail, code, details}`.
|
|
10
|
+
- **`X-NN` rules**: the codes cited in the descriptions (e.g. `rule O-02`, `rule D-01`) refer to the [business rules](business-rules.en.md) page, where each rule is detailed.
|
|
10
11
|
|
|
11
12
|
## Auth
|
|
12
13
|
|
|
@@ -7,6 +7,7 @@ Toda a API REST do marketplace numa tabela só, pronta pra colar no contrato do
|
|
|
7
7
|
- **Idem**: ✅ = aceita `Idempotency-Key` (cacheado pelo `IdempotencyMiddleware`).
|
|
8
8
|
- **Paginação**: cursor por padrão; offset onde explícito.
|
|
9
9
|
- **Erros**: todo erro vem no envelope SDK `{detail, code, details}`.
|
|
10
|
+
- **Regras `X-NN`**: os códigos citados nas descrições (ex.: `regra O-02`, `regra D-01`) remetem à página de [regras de negócio](business-rules.md), onde cada regra está detalhada.
|
|
10
11
|
|
|
11
12
|
## Auth
|
|
12
13
|
|
|
@@ -4,7 +4,6 @@ This page is the **domain contract**. Every modeling, endpoint, or test decision
|
|
|
4
4
|
|
|
5
5
|
!!! warning "Severity convention"
|
|
6
6
|
**MUST** = domain invariant, violation is a bug.
|
|
7
|
-
**SHOULD** = default behavior, override requires justification.
|
|
8
7
|
**MAY** = intentional opening, decided case by case.
|
|
9
8
|
|
|
10
9
|
## 1. Users
|
|
@@ -4,7 +4,6 @@ Esta página é o **contrato do domínio**. Toda decisão de modelagem, endpoint
|
|
|
4
4
|
|
|
5
5
|
!!! warning "Convenção de severidade"
|
|
6
6
|
**MUST** = invariante de domínio, violação é bug.
|
|
7
|
-
**SHOULD** = comportamento padrão, override exige justificativa.
|
|
8
7
|
**MAY** = abertura intencional, decidir caso a caso.
|
|
9
8
|
|
|
10
9
|
## 1. Usuários
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/domain.en.md
RENAMED
|
@@ -359,12 +359,12 @@ classDiagram
|
|
|
359
359
|
| `Product` | `BaseModel + AuditMixin + SoftDeleteMixin` | custom (JOINs variant+price) | `BaseService` |
|
|
360
360
|
| `ProductVariant` | `BaseModel + AuditMixin` | custom | `BaseService` |
|
|
361
361
|
| `PriceHistory` | `BaseModel` (no updated_at) | append-only | `BaseService` |
|
|
362
|
-
| `StockMovement` | `BaseModel` (no updated_at) | append-only via `
|
|
362
|
+
| `StockMovement` | `BaseModel` (no updated_at) | append-only via `bulk_create_values` when batching | `BaseService` |
|
|
363
363
|
| `Cart`/`CartItem` | `BaseModel + AuditMixin` | `BaseRepository[CartModel]` | `BaseService` |
|
|
364
364
|
| `Order`/`OrderItem` | `BaseModel + AuditMixin` | custom | `BaseService` |
|
|
365
365
|
| `Review` | `BaseModel + AuditMixin` | `BaseRepository[ReviewModel]` | `BaseService` |
|
|
366
366
|
|
|
367
|
-
`PriceHistory` and `StockMovement` are append-only, so their repository **doesn't expose `update` or `delete`** — only `
|
|
367
|
+
`PriceHistory` and `StockMovement` are append-only, so their repository **doesn't expose `update` or `delete`** — only `add`/`list`/`get`. That prevents accidental ALTER on history.
|
|
368
368
|
|
|
369
369
|
## Next step
|
|
370
370
|
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/domain.md
RENAMED
|
@@ -359,12 +359,12 @@ classDiagram
|
|
|
359
359
|
| `Product` | `BaseModel + AuditMixin + SoftDeleteMixin` | custom (com JOINs em variant+price) | `BaseService` |
|
|
360
360
|
| `ProductVariant` | `BaseModel + AuditMixin` | custom | `BaseService` |
|
|
361
361
|
| `PriceHistory` | `BaseModel` (sem updated_at) | append-only | `BaseService` |
|
|
362
|
-
| `StockMovement` | `BaseModel` (sem updated_at) | append-only via `
|
|
362
|
+
| `StockMovement` | `BaseModel` (sem updated_at) | append-only via `bulk_create_values` quando lote | `BaseService` |
|
|
363
363
|
| `Cart`/`CartItem` | `BaseModel + AuditMixin` | `BaseRepository[CartModel]` | `BaseService` |
|
|
364
364
|
| `Order`/`OrderItem` | `BaseModel + AuditMixin` | custom | `BaseService` |
|
|
365
365
|
| `Review` | `BaseModel + AuditMixin` | `BaseRepository[ReviewModel]` | `BaseService` |
|
|
366
366
|
|
|
367
|
-
`PriceHistory` e `StockMovement` são append-only, então o repositório deles **não expõe `update` nem `delete`** — só `
|
|
367
|
+
`PriceHistory` e `StockMovement` são append-only, então o repositório deles **não expõe `update` nem `delete`** — só `add`/`list`/`get`. Isso impede ALTER acidental no histórico.
|
|
368
368
|
|
|
369
369
|
## Próximo passo
|
|
370
370
|
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/flows.en.md
RENAMED
|
@@ -76,11 +76,14 @@ sequenceDiagram
|
|
|
76
76
|
|
|
77
77
|
**SDK touchpoints:**
|
|
78
78
|
|
|
79
|
-
- `generate_opaque_token(48)` returns `(plain, hash)`.
|
|
79
|
+
- `generate_opaque_token(48)` returns `(plain, hash)`.
|
|
80
80
|
- `EmailUtils.render_template("invitation.html", ctx)` (v0.24+).
|
|
81
81
|
- Send is async (TaskIQ) — endpoint returns `201` without waiting on SMTP.
|
|
82
82
|
- The acceptance is **one single transaction** — membership + invitation status are atomic.
|
|
83
83
|
|
|
84
|
+
!!! warning "The database stores only the hash"
|
|
85
|
+
`generate_opaque_token(48)` returns `(plain, hash)`: the `plain` value only ever lives in the email sent to the invitee, and the database persists just `hash`. On acceptance the service calls `hash_opaque_token(plain)` and looks the row up by hash — a leak of the `invitations` table exposes no usable tokens.
|
|
86
|
+
|
|
84
87
|
## 3. Create product + variant + images
|
|
85
88
|
|
|
86
89
|
```mermaid
|
|
@@ -91,7 +94,7 @@ sequenceDiagram
|
|
|
91
94
|
participant CT as ProductController
|
|
92
95
|
participant PS as ProductService
|
|
93
96
|
participant VS as VariantService
|
|
94
|
-
participant ST as
|
|
97
|
+
participant ST as AsyncMinIOClient
|
|
95
98
|
participant DB as Postgres
|
|
96
99
|
|
|
97
100
|
M->>R: POST /products {title, description, variants:[{sku, attrs, price_cents}]}
|
|
@@ -123,7 +126,7 @@ sequenceDiagram
|
|
|
123
126
|
**SDK touchpoints:**
|
|
124
127
|
|
|
125
128
|
- Product creation is a single transaction — product + variants + first `PriceHistory` row.
|
|
126
|
-
- Images **never flow through the API** — the client `PUT`s directly to MinIO via a presigned URL (`MinIOUploadStorage.presigned_url`
|
|
129
|
+
- Images **never flow through the API** — the client `PUT`s directly to MinIO via a presigned URL minted by `AsyncMinIOClient.presigned_put_url` (`MinIOUploadStorage.presigned_url` is GET/read-only and cannot be used for upload).
|
|
127
130
|
- The public catalog reads `image_keys` and mints presigned read URLs (1h TTL).
|
|
128
131
|
|
|
129
132
|
## 4. Idempotent checkout
|
|
@@ -172,11 +175,14 @@ sequenceDiagram
|
|
|
172
175
|
|
|
173
176
|
**SDK touchpoints:**
|
|
174
177
|
|
|
175
|
-
- `IdempotencyMiddleware` covers the endpoint without the handler having to care.
|
|
178
|
+
- `IdempotencyMiddleware` covers the endpoint without the handler having to care.
|
|
176
179
|
- Stock reservation lives **inside the same transaction** as the order `INSERT`. A failure on any item rolls everything back.
|
|
177
180
|
- The `SSE` notifies the stream (the buyer's client listening on `/orders/{id}/events`).
|
|
178
181
|
- `notify_seller` is queued — does not block the checkout response.
|
|
179
182
|
|
|
183
|
+
!!! note "Idempotency prevents double stock decrement"
|
|
184
|
+
If the buyer retries with the same `Idempotency-Key` (reload, network timeout, double-tap), the middleware replays the original response — the handler **does not run twice**, so stock is **not decremented twice** and no duplicate order is created.
|
|
185
|
+
|
|
180
186
|
## 5. Shipping + real-time updates
|
|
181
187
|
|
|
182
188
|
```mermaid
|
|
@@ -234,7 +240,8 @@ stateDiagram-v2
|
|
|
234
240
|
RETURNED --> [*]
|
|
235
241
|
```
|
|
236
242
|
|
|
237
|
-
|
|
243
|
+
!!! warning "Invalid transitions must fail with ConflictException"
|
|
244
|
+
Forbidden transitions (any other arrow) **MUST** fail with `ConflictException("invalid state transition")`. Typical implementation is an enum + `dict[from, set[to]]` in the service.
|
|
238
245
|
|
|
239
246
|
## State machine — Invitation
|
|
240
247
|
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/flows.md
RENAMED
|
@@ -76,11 +76,14 @@ sequenceDiagram
|
|
|
76
76
|
|
|
77
77
|
**Pontos do SDK:**
|
|
78
78
|
|
|
79
|
-
- `generate_opaque_token(48)` retorna par `(plain, hash)`.
|
|
79
|
+
- `generate_opaque_token(48)` retorna par `(plain, hash)`.
|
|
80
80
|
- `EmailUtils.render_template("invitation.html", ctx)` (v0.24+).
|
|
81
81
|
- O envio é assíncrono (TaskIQ) — endpoint retorna `201` sem esperar SMTP.
|
|
82
82
|
- Toda a aceitação é **uma única transação** — membership + status do convite são atomic.
|
|
83
83
|
|
|
84
|
+
!!! warning "O banco guarda só o hash"
|
|
85
|
+
`generate_opaque_token(48)` devolve `(plain, hash)`: o valor `plain` só existe no email enviado ao convidado, e o banco persiste apenas `hash`. Na aceitação, o service faz `hash_opaque_token(plain)` e busca pelo hash — um vazamento da tabela `invitations` não expõe tokens utilizáveis.
|
|
86
|
+
|
|
84
87
|
## 3. Criar produto com variante + imagens
|
|
85
88
|
|
|
86
89
|
```mermaid
|
|
@@ -91,7 +94,7 @@ sequenceDiagram
|
|
|
91
94
|
participant CT as ProductController
|
|
92
95
|
participant PS as ProductService
|
|
93
96
|
participant VS as VariantService
|
|
94
|
-
participant ST as
|
|
97
|
+
participant ST as AsyncMinIOClient
|
|
95
98
|
participant DB as Postgres
|
|
96
99
|
|
|
97
100
|
M->>R: POST /products {title, description, variants:[{sku, attrs, price_cents}]}
|
|
@@ -123,7 +126,7 @@ sequenceDiagram
|
|
|
123
126
|
**Pontos do SDK:**
|
|
124
127
|
|
|
125
128
|
- Criação de produto é transação única — produto + variantes + primeira linha de `PriceHistory`.
|
|
126
|
-
- Imagens **não trafegam pela API** — cliente faz `PUT` direto no MinIO via URL presigned (`MinIOUploadStorage.presigned_url`
|
|
129
|
+
- Imagens **não trafegam pela API** — cliente faz `PUT` direto no MinIO via URL presigned gerada por `AsyncMinIOClient.presigned_put_url` (o `MinIOUploadStorage.presigned_url` é GET/leitura, não serve pra upload).
|
|
127
130
|
- Catálogo público lê `image_keys` e gera URLs presigned de leitura (TTL 1h).
|
|
128
131
|
|
|
129
132
|
## 4. Checkout idempotente
|
|
@@ -172,11 +175,14 @@ sequenceDiagram
|
|
|
172
175
|
|
|
173
176
|
**Pontos do SDK:**
|
|
174
177
|
|
|
175
|
-
- `IdempotencyMiddleware` cobre o endpoint sem o handler precisar saber.
|
|
178
|
+
- `IdempotencyMiddleware` cobre o endpoint sem o handler precisar saber.
|
|
176
179
|
- Reserva de estoque é **dentro da mesma transação** do `INSERT` do pedido. Falha em qualquer item aborta tudo.
|
|
177
180
|
- A `SSE` notifica o stream (cliente do comprador escutando em `/orders/{id}/events`).
|
|
178
181
|
- O notify_seller vai pra fila — não bloqueia a resposta do checkout.
|
|
179
182
|
|
|
183
|
+
!!! note "Idempotência evita decremento duplo de estoque"
|
|
184
|
+
Se o comprador retentar com a mesma `Idempotency-Key` (reload, timeout de rede, double-tap), o middleware devolve a resposta original — o handler **não roda 2x**, então o estoque **não é decrementado 2x** e nenhum pedido duplicado é criado.
|
|
185
|
+
|
|
180
186
|
## 5. Expedição + atualização em tempo real
|
|
181
187
|
|
|
182
188
|
```mermaid
|
|
@@ -234,7 +240,8 @@ stateDiagram-v2
|
|
|
234
240
|
RETURNED --> [*]
|
|
235
241
|
```
|
|
236
242
|
|
|
237
|
-
|
|
243
|
+
!!! warning "Transições inválidas devem falhar com ConflictException"
|
|
244
|
+
Transições proibidas (qualquer outra setinha) **MUST** falhar com `ConflictException("invalid state transition")`. Implementação típica num enum + `dict[from, set[to]]` no service.
|
|
238
245
|
|
|
239
246
|
## Máquina de estados — Invitation
|
|
240
247
|
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/index.en.md
RENAMED
|
@@ -45,6 +45,9 @@ When the service boots you have:
|
|
|
45
45
|
- **RabbitMQ UI** at `http://localhost:15672` (`guest/guest`)
|
|
46
46
|
- **MailHog UI** at `http://localhost:8025`
|
|
47
47
|
|
|
48
|
+
!!! warning "Local-development credentials only"
|
|
49
|
+
The logins and passwords above (`minioadmin/minioadmin`, `guest/guest`, the `admin-pass-12` admin) are local-development defaults. Never deploy with them: rotate or replace every one with strong secrets before any shared or production environment.
|
|
50
|
+
|
|
48
51
|
## SDK stack exercised
|
|
49
52
|
|
|
50
53
|
| Need | SDK primitive |
|
{tempest_fastapi_sdk-0.89.0 → tempest_fastapi_sdk-0.91.0}/docs/learning/marketplace/index.md
RENAMED
|
@@ -45,6 +45,9 @@ Quando o serviço subir você terá:
|
|
|
45
45
|
- **RabbitMQ UI** em `http://localhost:15672` (`guest/guest`)
|
|
46
46
|
- **MailHog UI** em `http://localhost:8025`
|
|
47
47
|
|
|
48
|
+
!!! warning "Credenciais só de desenvolvimento local"
|
|
49
|
+
Os logins e senhas acima (`minioadmin/minioadmin`, `guest/guest`, o admin `admin-pass-12`) são padrões de desenvolvimento local. Nunca faça deploy com eles: rotacione ou substitua todos por segredos fortes antes de qualquer ambiente compartilhado ou de produção.
|
|
50
|
+
|
|
48
51
|
## Stack do SDK exercitada
|
|
49
52
|
|
|
50
53
|
| Necessidade | Primitivo do SDK |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Migration guide
|
|
2
2
|
|
|
3
|
-
Breaking-change walkthroughs grouped by minor release. Stick to the version that matches what you're upgrading **from**.
|
|
3
|
+
Breaking-change walkthroughs grouped by minor release. Stick to the version that matches what you're upgrading **from**. The release sections are listed newest-first, so on a multi-version jump read and apply them bottom-up.
|
|
4
4
|
|
|
5
5
|
## 0.63.0 — authenticated user loaded on the request session
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Guia de migração
|
|
2
2
|
|
|
3
|
-
Passo a passo das mudanças que quebram compatibilidade, agrupadas por release minor. Siga a versão que casa com aquela **de onde** você está atualizando.
|
|
3
|
+
Passo a passo das mudanças que quebram compatibilidade, agrupadas por release minor. Siga a versão que casa com aquela **de onde** você está atualizando. As seções estão listadas da mais nova para a mais antiga, então num salto de várias versões leia e aplique-as de baixo para cima.
|
|
4
4
|
|
|
5
5
|
## 0.63.0 — usuário autenticado carregado na sessão de request
|
|
6
6
|
|