tempest-fastapi-sdk 0.91.0__tar.gz → 0.92.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.91.0 → tempest_fastapi_sdk-0.92.0}/CHANGELOG.md +60 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/CLAUDE.md +15 -7
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/PKG-INFO +2 -2
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/README.md +1 -1
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/migration.en.md +30 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/migration.md +30 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/auth-flow.en.md +49 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/auth-flow.md +49 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/pyproject.toml +1 -1
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/__init__.py +13 -1
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/__init__.py +22 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/locale.py +24 -4
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/router.py +240 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/schemas.py +223 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/service.py +423 -1
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_change.html +20 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_change_error.html +27 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_change_success.html +23 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_changed_notice.html +10 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_verification.html +19 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_verification_error.html +26 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/en-US/email_verification_success.html +23 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_change.html +20 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_change_error.html +27 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_change_success.html +23 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_changed_notice.html +10 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification.html +19 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification_error.html +26 -0
- tempest_fastapi_sdk-0.92.0/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification_success.html +23 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/user_token_model.py +18 -2
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/settings/mixins.py +138 -0
- tempest_fastapi_sdk-0.92.0/tests/auth/test_email_change.py +472 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/uv.lock +1 -1
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/.github/workflows/ci.yml +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/.github/workflows/docs.yml +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/.gitignore +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/.python-version +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/Makefile +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/architecture.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/architecture.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/changelog.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/changelog.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/contributing.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/contributing.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/index.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/index.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/installation.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/installation.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/index.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/index.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/api.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/api.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/business-rules.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/business-rules.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/domain.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/domain.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/flows.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/flows.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/index.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/learning/marketplace/index.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/admin.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/admin.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/audit-trail.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/audit-trail.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/br-helpers.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/br-helpers.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/cache.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/cache.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/cli.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/cli.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/database.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/database.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/deploy-safety.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/deploy-safety.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/downloads.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/downloads.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/email.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/email.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/feature-flags.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/feature-flags.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/fields.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/fields.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/file-store.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/file-store.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/http-client.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/http-client.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/http.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/http.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/idempotency.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/idempotency.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/index.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/index.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/logging.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/logging.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/metrics.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/metrics.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/mfa.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/mfa.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/multi-tenant.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/multi-tenant.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/observability.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/observability.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/offline-sync.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/offline-sync.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/outbox.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/outbox.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/queue-tasks.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/queue-tasks.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/realtime.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/realtime.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/refresh-tokens.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/refresh-tokens.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/security.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/security.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/sessions.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/sessions.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/sse.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/sse.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/storage.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/storage.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/stored-files.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/stored-files.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/testing.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/testing.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/typing.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/typing.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/uploads.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/uploads.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/utilities.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/utilities.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/vision.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/vision.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/webpush.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/webpush.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/websocket.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/recipes/websocket.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/reference.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/reference.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/roadmap.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/roadmap.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/ssr.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/ssr.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/tutorial.en.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/docs/tutorial.md +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/mkdocs.yml +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/mkdocs_hooks/llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/scripts/extract_recipe.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/actions.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/auth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/config.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/discovery.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/forms.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/session.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/site.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/static/admin.css +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/detail.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/form.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/list.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/logs.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/templates/mfa.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/admin/theme.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/dependencies/auth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/graceful.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/server.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/static.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/tracing.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/guards.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/activation.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/token_delivery.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cache/invalidation.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/Dockerfile.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/dockerignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/resources.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/config.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/db.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/main.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/new.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/secrets.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/src_layers.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/cli/user.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/controllers/base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/core/context.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/core/enums.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/core/logging.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/core/typed.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/audit.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/backup.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/connection.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/mixins.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/outbox.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/repository.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/slow_query.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/tenant.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/user_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/user_recovery_code_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/user_refresh_token_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/db/webpush_subscription_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/i18n.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/flags/backends.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/flags/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/flags/service.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/py.typed +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/services/base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/services/file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/settings/base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sse/broker.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/sse/event_stream.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/ssr/_static/htmx.min.js +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/ssr/assets.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/ssr/page.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/ssr/response.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/storage/minio_client.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/testing/database.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/data/br_locations.json +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/download.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/email.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/fields.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/file_store.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/locations.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/log.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/password.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/totp.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/utils/upload.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/vision/mapping.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/vision/schemas.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/webpush/router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/webpush/service.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_actions.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_auth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_discovery.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_forms.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_logs_nav.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_rich_filters.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_site.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_theme.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_upload_field.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/admin/test_user_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_body_size.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_cookies.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_cors.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_csrf.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_dependencies_auth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_graceful.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_handlers.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_health_router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_idempotency.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_jwt_dependency.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_logs_router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_oauth.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_prometheus.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_rate_limit_extras.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_request_id_middleware.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_role_dependency.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_server.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_static.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/api/test_webhooks_rsa.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_cookie_delivery.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_guards.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_locale.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_refresh.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_refresh_db.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/auth/test_service.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cache/test_decorator.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cache/test_invalidation.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cache/test_redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_config.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_db.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_db_seed.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_lint_strictness.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_main.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_secrets.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/cli/test_user.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/conftest.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/controllers/test_base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/core/test_context.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/core/test_enums.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/core/test_logging.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/core/test_typed.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_audit.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_backup.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_bulk_ops.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_connection.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_migrations.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_model.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_outbox.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_repository.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_safe_upgrade.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_slow_query.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/db/test_tenant.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/exceptions/test_exceptions.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/exceptions/test_i18n.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/flags/test_flags.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/queue/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/test_base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/test_cursor_pagination.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/test_link_headers.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/test_pagination.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/schemas/test_response.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/services/test_base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/services/test_file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/sessions/test_sessions.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/settings/test_base.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/settings/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/sse/test_broker.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/sse/test_event_stream.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/ssr/test_integration.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/ssr/test_page.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/ssr/test_response.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/storage/test_minio_client.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/tasks/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/tasks/test_scheduler.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/testing/test_database.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_client_ip.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_datetime.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_dict.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_download.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_email.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_fields.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_file_store.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_http_client.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_jwt.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_lazy_extras.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_locations.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_log.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_metrics.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_password.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_regex.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_throttle.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/utils/test_upload.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/vision/test_vision.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/webpush/test_dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/webpush/test_router.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/webpush/test_schemas.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/webpush/test_service.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tests/websockets/test_hub_and_router.py +0 -0
|
@@ -5,6 +5,66 @@ 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.92.0] — 2026-07-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Email change / re-verification / recovery flow** on `UserAuthService`
|
|
13
|
+
+ `make_auth_router`, mirroring the password reset/change surface:
|
|
14
|
+
- **Change email (authenticated)** — `request_email_change` (verifies
|
|
15
|
+
the current password, stages the new address, emails a confirmation
|
|
16
|
+
link to the NEW address) + `confirm_email_change` (consumes the
|
|
17
|
+
token, flips the email, and — when `AUTH_EMAIL_CHANGE_NOTIFY_OLD`
|
|
18
|
+
is on — sends a security notice to the OLD address). Routes:
|
|
19
|
+
`POST /auth/email-change/request` (202) and
|
|
20
|
+
`POST /auth/email-change/confirm`.
|
|
21
|
+
- **Re-verify current email** — `request_email_verification` /
|
|
22
|
+
`confirm_email_verification` (resend a verification link to the
|
|
23
|
+
current address; confirming marks the account active). Routes:
|
|
24
|
+
`POST /auth/email-verify/request` (202) and
|
|
25
|
+
`POST /auth/email-verify/confirm`.
|
|
26
|
+
- **Recovery (lost mailbox access)** — `request_email_recovery`, an
|
|
27
|
+
**unauthenticated** entry point that proves identity with the
|
|
28
|
+
account password **plus a valid MFA code when TOTP is enrolled**,
|
|
29
|
+
then emails the confirmation link to the new address. Always returns
|
|
30
|
+
a generic `202` for soft failures (unknown email, wrong password,
|
|
31
|
+
bad/missing MFA code) so it can't enumerate accounts. Route
|
|
32
|
+
`POST /auth/email-recovery/request` is **opt-in** via
|
|
33
|
+
`AUTH_EMAIL_RECOVERY_ENABLED` (off by default).
|
|
34
|
+
- **Old-email security notice** on a confirmed change, toggled by
|
|
35
|
+
`AUTH_EMAIL_CHANGE_NOTIFY_OLD` (default `True`).
|
|
36
|
+
- **Backend HTML pages** (when `AUTH_BACKEND_LINKS=True`):
|
|
37
|
+
`GET /auth/email-change/{token}` and `GET /auth/email-verify/{token}`
|
|
38
|
+
render self-contained success/error pages — no frontend needed.
|
|
39
|
+
- New schemas exported from the package root:
|
|
40
|
+
`EmailChangeRequestSchema`, `EmailChangeConfirmSchema`,
|
|
41
|
+
`EmailRecoveryRequestSchema`, `EmailChangeResponseSchema`,
|
|
42
|
+
`EmailChangeToken`, `EmailVerificationToken`.
|
|
43
|
+
- New `UserTokenPurpose.EMAIL_CHANGE`; the existing
|
|
44
|
+
`EMAIL_VERIFICATION` purpose now backs the re-verify flow.
|
|
45
|
+
- 14 bundled bilingual templates (PT-BR + EN-US): `email_change.html`,
|
|
46
|
+
`email_verification.html`, `email_changed_notice.html`, plus
|
|
47
|
+
`email_change_success/error.html` and
|
|
48
|
+
`email_verification_success/error.html`.
|
|
49
|
+
- Localized subjects/bodies for the three new emails.
|
|
50
|
+
- New settings: `AUTH_EMAIL_CHANGE_TTL_SECONDS`,
|
|
51
|
+
`AUTH_EMAIL_VERIFICATION_TTL_SECONDS`,
|
|
52
|
+
`AUTH_EMAIL_CHANGE_URL_TEMPLATE`,
|
|
53
|
+
`AUTH_EMAIL_VERIFICATION_URL_TEMPLATE`, `AUTH_EMAIL_CHANGE_TEMPLATE`,
|
|
54
|
+
`AUTH_EMAIL_VERIFICATION_TEMPLATE`,
|
|
55
|
+
`AUTH_EMAIL_CHANGED_NOTICE_TEMPLATE`, `AUTH_EMAIL_CHANGE_NOTIFY_OLD`,
|
|
56
|
+
`AUTH_EMAIL_RECOVERY_ENABLED`, `AUTH_EMAIL_CHANGE_SUCCESS_TEMPLATE`,
|
|
57
|
+
`AUTH_EMAIL_CHANGE_ERROR_TEMPLATE`,
|
|
58
|
+
`AUTH_EMAIL_VERIFICATION_SUCCESS_TEMPLATE`,
|
|
59
|
+
`AUTH_EMAIL_VERIFICATION_ERROR_TEMPLATE`.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- **`BaseUserTokenModel` gains a nullable `payload` column**
|
|
64
|
+
(`VARCHAR(320)`) carrying flow context — the pending new email for an
|
|
65
|
+
`EMAIL_CHANGE` token. **Requires a migration** in consuming projects
|
|
66
|
+
(additive nullable column, safe). See the migration guide.
|
|
67
|
+
|
|
8
68
|
## [0.91.0] — 2026-07-05
|
|
9
69
|
|
|
10
70
|
### Added
|
|
@@ -60,13 +60,21 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
60
60
|
`query_param=`, for cookieless `EventSource`/SSE clients), full
|
|
61
61
|
bundled flow (`UserAuthService` + `make_auth_router` covering
|
|
62
62
|
signup/activate/login/password-reset), `BaseUserModel` +
|
|
63
|
-
`BaseUserTokenModel
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`
|
|
68
|
-
`
|
|
69
|
-
|
|
63
|
+
`BaseUserTokenModel` (nullable `payload` column carrying flow
|
|
64
|
+
context), email change/re-verify/recovery
|
|
65
|
+
(`request_email_change`/`confirm_email_change`,
|
|
66
|
+
`request_email_verification`/`confirm_email_verification`,
|
|
67
|
+
`request_email_recovery` — password + MFA-if-enrolled, opt-in
|
|
68
|
+
`AUTH_EMAIL_RECOVERY_ENABLED`; old-email security notice via
|
|
69
|
+
`AUTH_EMAIL_CHANGE_NOTIFY_OLD`; `EMAIL_CHANGE` token purpose;
|
|
70
|
+
JSON + backend HTML pages + bilingual templates), OAuth2/OIDC
|
|
71
|
+
providers (`GoogleOAuthClient`, `GitHubOAuthClient`,
|
|
72
|
+
`OIDCProvider`), CSRF middleware + `make_csrf_token_dependency`,
|
|
73
|
+
opt-in DB-backed opaque refresh tokens
|
|
74
|
+
(`BaseUserRefreshTokenModel`, `make_user_refresh_token_model`,
|
|
75
|
+
`refresh_token_model=` on `UserAuthService`) with rotation,
|
|
76
|
+
family-wide reuse detection and `POST /auth/logout`
|
|
77
|
+
(`LogoutSchema`).
|
|
70
78
|
- **DB** — `AsyncDatabaseManager`, `BaseRepository[T]` with
|
|
71
79
|
bulk ops (`bulk_create_values`, `bulk_upsert`, `bulk_update`,
|
|
72
80
|
`add_all`, etc.), `AlembicHelper`, `BaseModel`, audit /
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempest-fastapi-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.92.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
|
|
@@ -253,7 +253,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
253
253
|
| `tempest_fastapi_sdk.exceptions` | `AppException`, `NotFoundException`, `ConflictException`, `ValidationException`, `UnauthorizedException`, `ForbiddenException`, `InvalidTokenException`, `ExpiredTokenException`, `FileTooLargeException`, `InvalidFileTypeException`, `TooManyRequestsException`, i18n (`MessageCatalog`, `default_message_catalog`, `parse_accept_language`, `DEFAULT_LOCALE`) |
|
|
254
254
|
| `tempest_fastapi_sdk.settings` | `BaseAppSettings`, `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
|
|
255
255
|
| `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `LogSource`, `make_tool_spec_router`, `make_token_dependency`, `make_bearer_token_dependency`, `make_jwt_user_dependency`, `make_role_dependency`, `make_permission_dependency`, `require_x_token`, `run_server`, `RequestIDMiddleware`, `RateLimitMiddleware` (+ `RateLimitStore`/`MemoryRateLimitStore`/`RedisRateLimitStore`/`RateLimitResult` and `key_by_ip`/`key_by_jwt_subject`/`key_by_jwt_claim`/`key_by_header`), `IdempotencyMiddleware`, `MemoryIdempotencyStore`, `RedisIdempotencyStore`, `BodySizeLimitMiddleware`, `CSRFMiddleware`, `make_csrf_token_dependency`, `GracefulShutdownMiddleware`, `WebhookSignatureVerifier`, `RSAWebhookSignatureVerifier`, OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck`, `setup_tracing` *(extra: `[otel]`)* |
|
|
256
|
-
| `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `RefreshSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`), opt-in DB-backed refresh tokens (`BaseUserRefreshTokenModel` / `make_user_refresh_token_model` / `LogoutSchema`) with rotation + reuse detection + `POST /auth/logout`, bilingual emails + backend pages (`AUTH_DEFAULT_LOCALE`, `normalize_locale` / `negotiate_locale`) — signup/activate/login/refresh/logout/reset + TOTP 2FA out of the box |
|
|
256
|
+
| `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `RefreshSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, email change/verify/recovery (`EmailChangeRequestSchema` / `EmailChangeConfirmSchema` / `EmailRecoveryRequestSchema` / `EmailChangeToken` / `EmailVerificationToken`, old-email security notice, opt-in `AUTH_EMAIL_RECOVERY_ENABLED`), MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`), opt-in DB-backed refresh tokens (`BaseUserRefreshTokenModel` / `make_user_refresh_token_model` / `LogoutSchema`) with rotation + reuse detection + `POST /auth/logout`, bilingual emails + backend pages (`AUTH_DEFAULT_LOCALE`, `normalize_locale` / `negotiate_locale`) — signup/activate/login/refresh/logout/reset + email change/recovery + TOTP 2FA out of the box |
|
|
257
257
|
| `tempest_fastapi_sdk.controllers` | `BaseController` |
|
|
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` |
|
|
@@ -144,7 +144,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
144
144
|
| `tempest_fastapi_sdk.exceptions` | `AppException`, `NotFoundException`, `ConflictException`, `ValidationException`, `UnauthorizedException`, `ForbiddenException`, `InvalidTokenException`, `ExpiredTokenException`, `FileTooLargeException`, `InvalidFileTypeException`, `TooManyRequestsException`, i18n (`MessageCatalog`, `default_message_catalog`, `parse_accept_language`, `DEFAULT_LOCALE`) |
|
|
145
145
|
| `tempest_fastapi_sdk.settings` | `BaseAppSettings`, `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
|
|
146
146
|
| `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `LogSource`, `make_tool_spec_router`, `make_token_dependency`, `make_bearer_token_dependency`, `make_jwt_user_dependency`, `make_role_dependency`, `make_permission_dependency`, `require_x_token`, `run_server`, `RequestIDMiddleware`, `RateLimitMiddleware` (+ `RateLimitStore`/`MemoryRateLimitStore`/`RedisRateLimitStore`/`RateLimitResult` and `key_by_ip`/`key_by_jwt_subject`/`key_by_jwt_claim`/`key_by_header`), `IdempotencyMiddleware`, `MemoryIdempotencyStore`, `RedisIdempotencyStore`, `BodySizeLimitMiddleware`, `CSRFMiddleware`, `make_csrf_token_dependency`, `GracefulShutdownMiddleware`, `WebhookSignatureVerifier`, `RSAWebhookSignatureVerifier`, OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck`, `setup_tracing` *(extra: `[otel]`)* |
|
|
147
|
-
| `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `RefreshSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`), opt-in DB-backed refresh tokens (`BaseUserRefreshTokenModel` / `make_user_refresh_token_model` / `LogoutSchema`) with rotation + reuse detection + `POST /auth/logout`, bilingual emails + backend pages (`AUTH_DEFAULT_LOCALE`, `normalize_locale` / `negotiate_locale`) — signup/activate/login/refresh/logout/reset + TOTP 2FA out of the box |
|
|
147
|
+
| `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `RefreshSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, email change/verify/recovery (`EmailChangeRequestSchema` / `EmailChangeConfirmSchema` / `EmailRecoveryRequestSchema` / `EmailChangeToken` / `EmailVerificationToken`, old-email security notice, opt-in `AUTH_EMAIL_RECOVERY_ENABLED`), MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`), opt-in DB-backed refresh tokens (`BaseUserRefreshTokenModel` / `make_user_refresh_token_model` / `LogoutSchema`) with rotation + reuse detection + `POST /auth/logout`, bilingual emails + backend pages (`AUTH_DEFAULT_LOCALE`, `normalize_locale` / `negotiate_locale`) — signup/activate/login/refresh/logout/reset + email change/recovery + TOTP 2FA out of the box |
|
|
148
148
|
| `tempest_fastapi_sdk.controllers` | `BaseController` |
|
|
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` |
|
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
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
|
+
## 0.92.0 — `payload` column on the user token
|
|
6
|
+
|
|
7
|
+
0.92.0 adds the **email change / re-verification / recovery** flow. To carry the pending email until confirmation, `BaseUserTokenModel` gained a new column:
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
payload: Mapped[str | None] = mapped_column(String(320), nullable=True, default=None)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Since your `user_tokens` table inherits from `BaseUserTokenModel`, the column shows up on the model automatically — but the database needs a **migration**. It is additive and safe (nullable column, no required default):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# generate and apply
|
|
17
|
+
tempest db revision -m "add payload to user_tokens"
|
|
18
|
+
tempest db upgrade
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or by hand:
|
|
22
|
+
|
|
23
|
+
```sql
|
|
24
|
+
ALTER TABLE user_tokens ADD COLUMN payload VARCHAR(320) NULL;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
!!! info "That's it"
|
|
28
|
+
No renames, no default backfill. Existing flows (activation, password reset) keep writing `payload = NULL`. The new email flow is fully opt-in — recovery (`POST /auth/email-recovery/request`) is only mounted with `AUTH_EMAIL_RECOVERY_ENABLED=True`.
|
|
29
|
+
|
|
30
|
+
### Verify
|
|
31
|
+
|
|
32
|
+
- Run the migration before deploying 0.92.0 (the column must exist).
|
|
33
|
+
- If you hand-write `src/db/models/user_token.py` instead of using `make_user_token_model`, the column comes from the abstract base — no need to redeclare, just migrate.
|
|
34
|
+
|
|
5
35
|
## 0.63.0 — authenticated user loaded on the request session
|
|
6
36
|
|
|
7
37
|
Before 0.63.0, `UserAuthService.current_user_dependency()` loaded the authenticated user through `load_user`, which opened its **own** session (via `db.get_session_context()`) and closed it on exit. The `UserModel` handed to the route was therefore **detached**: mutating it and calling `commit`/`refresh` on the request session (the one your repositories use) raised
|
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
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
|
+
## 0.92.0 — coluna `payload` no token de usuário
|
|
6
|
+
|
|
7
|
+
A 0.92.0 adiciona o fluxo de **troca / re-verificação / recuperação de e-mail**. Para carregar o e-mail pendente até a confirmação, `BaseUserTokenModel` ganhou uma coluna nova:
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
payload: Mapped[str | None] = mapped_column(String(320), nullable=True, default=None)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Como sua tabela `user_tokens` herda de `BaseUserTokenModel`, a coluna aparece automaticamente no modelo — mas o banco precisa de uma **migration**. É aditiva e segura (coluna anulável, sem default obrigatório):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# gere e aplique
|
|
17
|
+
tempest db revision -m "add payload to user_tokens"
|
|
18
|
+
tempest db upgrade
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Ou, na mão:
|
|
22
|
+
|
|
23
|
+
```sql
|
|
24
|
+
ALTER TABLE user_tokens ADD COLUMN payload VARCHAR(320) NULL;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
!!! info "Só isso"
|
|
28
|
+
Nenhuma renomeação, nenhum default backfill. Fluxos existentes (ativação, reset de senha) continuam gravando `payload = NULL`. O novo fluxo de e-mail é totalmente opt-in — a recuperação (`POST /auth/email-recovery/request`) só é montada com `AUTH_EMAIL_RECOVERY_ENABLED=True`.
|
|
29
|
+
|
|
30
|
+
### Verifique
|
|
31
|
+
|
|
32
|
+
- Rode a migration antes de subir a 0.92.0 (a coluna precisa existir).
|
|
33
|
+
- Se você escreve `src/db/models/user_token.py` à mão em vez de usar `make_user_token_model`, a coluna vem da base abstrata — não precisa redeclarar, só migrar.
|
|
34
|
+
|
|
5
35
|
## 0.63.0 — usuário autenticado carregado na sessão de request
|
|
6
36
|
|
|
7
37
|
Antes da 0.63.0, `UserAuthService.current_user_dependency()` carregava o usuário autenticado chamando `load_user`, que abria a **própria** sessão (via `db.get_session_context()`) e a fechava ao terminar. O `UserModel` entregue à rota ficava **detached**: mutá-lo e dar `commit`/`refresh` na sessão de request (a dos seus repositories) levantava
|
|
@@ -130,6 +130,11 @@ uv run tempest db upgrade
|
|
|
130
130
|
| POST | `/auth/password-reset/request` | `PasswordResetRequestSchema` → `PasswordResetResponseSchema` | Always HTTP 202 + generic body. Link via email (A/B) or body (C). |
|
|
131
131
|
| POST | `/auth/password-reset/confirm` | `PasswordResetConfirmSchema` → `LoginResponseSchema` | Consumes token + writes new password + issues JWT pair. |
|
|
132
132
|
| POST | `/auth/password-change` | `PasswordChangeSchema` → `204` | **Authenticated** (bearer token). Change your own password: confirm the current password + write the new one. No email token. |
|
|
133
|
+
| POST | `/auth/email-change/request` *(v0.92.0+)* | `EmailChangeRequestSchema` → `EmailChangeResponseSchema` | **Authenticated.** Confirm the current password + email a confirmation link to the **new** address. Always 202. |
|
|
134
|
+
| POST | `/auth/email-change/confirm` *(v0.92.0+)* | `EmailChangeConfirmSchema` → `EmailChangeResponseSchema` | Consume the token + apply the new email + (optionally) notify the old address. |
|
|
135
|
+
| POST | `/auth/email-verify/request` *(v0.92.0+)* | — → `EmailChangeResponseSchema` | **Authenticated.** Re-send a verification link to the **current** email. |
|
|
136
|
+
| POST | `/auth/email-verify/confirm` *(v0.92.0+)* | `EmailChangeConfirmSchema` → `EmailChangeResponseSchema` | Consume the token + mark the account active. |
|
|
137
|
+
| POST | `/auth/email-recovery/request` *(v0.92.0+, opt-in)* | `EmailRecoveryRequestSchema` → `EmailChangeResponseSchema` | **Unauthenticated.** Recover an account whose mailbox is lost: password (+ MFA if enrolled). Only mounted with `AUTH_EMAIL_RECOVERY_ENABLED=True`. Always 202. |
|
|
133
138
|
| POST | `/auth/refresh` *(v0.65.0+)* | `RefreshSchema` → `LoginResponseSchema` | Exchange a valid **refresh token** for a fresh JWT pair. **No email/password.** Rejects a replayed access token (401) and inactive accounts (403). |
|
|
134
139
|
|
|
135
140
|
!!! tip "`password-reset/confirm` vs `password-change` — which is which?"
|
|
@@ -145,6 +150,50 @@ uv run tempest db upgrade
|
|
|
145
150
|
`current_password`. No email or reset token involved. Returns
|
|
146
151
|
**204** and the current tokens stay valid.
|
|
147
152
|
|
|
153
|
+
## Email change, verification and recovery (v0.92.0+)
|
|
154
|
+
|
|
155
|
+
Mirrors the password flow, but for the account **email**. Three cases:
|
|
156
|
+
|
|
157
|
+
- **Change email (logged in)** — like `password-change`: the user is
|
|
158
|
+
logged in, confirms `current_password` and supplies `new_email`. A
|
|
159
|
+
confirmation link goes to the **new** address; the email only changes
|
|
160
|
+
once that link is confirmed. On confirmation a security notice is sent
|
|
161
|
+
to the **old** address (the banks/Google pattern).
|
|
162
|
+
- **Re-verify the current email** — re-send a verification link to the
|
|
163
|
+
current address (useful when the activation email was lost).
|
|
164
|
+
- **Recovery (lost mailbox access)** — an **unauthenticated** endpoint,
|
|
165
|
+
opt-in via `AUTH_EMAIL_RECOVERY_ENABLED`. Proves identity with the
|
|
166
|
+
password **and a valid MFA code when TOTP is enrolled**, then emails the
|
|
167
|
+
link to the new address.
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
# Change email (logged in) — token comes in the body in dev (mode C)
|
|
171
|
+
resp = await client.post(
|
|
172
|
+
"/auth/email-change/request",
|
|
173
|
+
json={"new_email": "new@example.com", "current_password": "current-pass"},
|
|
174
|
+
headers={"Authorization": f"Bearer {access_token}"},
|
|
175
|
+
)
|
|
176
|
+
confirm_url: str | None = resp.json()["confirm_url"] # None in prod (goes by email)
|
|
177
|
+
|
|
178
|
+
# ...user opens the link; the front extracts the token and confirms:
|
|
179
|
+
await client.post("/auth/email-change/confirm", json={"token": token})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
!!! danger "Recovery is sensitive — enable it deliberately"
|
|
183
|
+
`POST /auth/email-recovery/request` lets whoever has the password move
|
|
184
|
+
the account to another email **without** accessing the old mailbox. It
|
|
185
|
+
is only mounted with `AUTH_EMAIL_RECOVERY_ENABLED=True`. It always
|
|
186
|
+
answers a generic **202** (no account enumeration) and, when TOTP is
|
|
187
|
+
enrolled, requires a valid `mfa_code`. Keep
|
|
188
|
+
`AUTH_EMAIL_CHANGE_NOTIFY_OLD=True` so the old address is always
|
|
189
|
+
alerted.
|
|
190
|
+
|
|
191
|
+
!!! info "Where the new email is stored"
|
|
192
|
+
The pending address travels in the token's `payload` column
|
|
193
|
+
(`EMAIL_CHANGE`), not on the `UserModel`. Confirmation re-reads the
|
|
194
|
+
`payload`, re-checks the address is still free (a request→confirm race
|
|
195
|
+
→ **409**) and only then writes it. See the 0.92.0 migration note.
|
|
196
|
+
|
|
148
197
|
### Renewing the session with the refresh token
|
|
149
198
|
|
|
150
199
|
The `access_token` is short-lived by design (`JWT_ACCESS_TTL_SECONDS`,
|
|
@@ -130,6 +130,11 @@ uv run tempest db upgrade
|
|
|
130
130
|
| POST | `/auth/password-reset/request` | `PasswordResetRequestSchema` → `PasswordResetResponseSchema` | Sempre HTTP 202 + corpo genérico. Link via e-mail (A/B) ou no body (C). |
|
|
131
131
|
| POST | `/auth/password-reset/confirm` | `PasswordResetConfirmSchema` → `LoginResponseSchema` | Consome token + grava nova senha + emite JWT pair. |
|
|
132
132
|
| POST | `/auth/password-change` | `PasswordChangeSchema` → `204` | **Autenticado** (bearer token). Troca a própria senha: confirma a senha atual + grava a nova. Sem token de e-mail. |
|
|
133
|
+
| POST | `/auth/email-change/request` *(v0.92.0+)* | `EmailChangeRequestSchema` → `EmailChangeResponseSchema` | **Autenticado.** Confirma a senha atual + envia link de confirmação pro **novo** e-mail. Sempre 202. |
|
|
134
|
+
| POST | `/auth/email-change/confirm` *(v0.92.0+)* | `EmailChangeConfirmSchema` → `EmailChangeResponseSchema` | Consome o token + aplica o novo e-mail + (opcional) avisa o e-mail antigo. |
|
|
135
|
+
| POST | `/auth/email-verify/request` *(v0.92.0+)* | — → `EmailChangeResponseSchema` | **Autenticado.** Reenvia link de verificação pro e-mail **atual**. |
|
|
136
|
+
| POST | `/auth/email-verify/confirm` *(v0.92.0+)* | `EmailChangeConfirmSchema` → `EmailChangeResponseSchema` | Consome o token + marca a conta ativa. |
|
|
137
|
+
| POST | `/auth/email-recovery/request` *(v0.92.0+, opt-in)* | `EmailRecoveryRequestSchema` → `EmailChangeResponseSchema` | **Não autenticado.** Recupera conta cujo e-mail se perdeu: senha (+ MFA se inscrito). Só montado com `AUTH_EMAIL_RECOVERY_ENABLED=True`. Sempre 202. |
|
|
133
138
|
| POST | `/auth/refresh` *(v0.65.0+)* | `RefreshSchema` → `LoginResponseSchema` | Troca um **refresh token** válido por um JWT pair novo. **Sem email/senha.** Rejeita access token replayado (401) e conta inativa (403). |
|
|
134
139
|
|
|
135
140
|
!!! tip "`password-reset/confirm` vs `password-change` — qual é qual?"
|
|
@@ -144,6 +149,50 @@ uv run tempest db upgrade
|
|
|
144
149
|
nem token de reset. Retorna **204** e os tokens atuais continuam
|
|
145
150
|
válidos.
|
|
146
151
|
|
|
152
|
+
## Troca, verificação e recuperação de e-mail (v0.92.0+)
|
|
153
|
+
|
|
154
|
+
Espelha o fluxo de senha, mas pro **e-mail** da conta. Três cenários:
|
|
155
|
+
|
|
156
|
+
- **Trocar e-mail (logado)** — como `password-change`: o usuário está
|
|
157
|
+
logado, confirma a `current_password` e informa o `new_email`. Um link
|
|
158
|
+
de confirmação vai pro **novo** endereço; o e-mail só muda quando esse
|
|
159
|
+
link é confirmado. Ao confirmar, um aviso de segurança vai pro endereço
|
|
160
|
+
**antigo** (padrão de bancos/Google).
|
|
161
|
+
- **Re-verificar o e-mail atual** — reenvia um link de verificação pro
|
|
162
|
+
endereço atual (útil quando o e-mail de ativação se perdeu).
|
|
163
|
+
- **Recuperação (perdeu acesso ao e-mail)** — endpoint **não
|
|
164
|
+
autenticado**, opt-in via `AUTH_EMAIL_RECOVERY_ENABLED`. Prova
|
|
165
|
+
identidade com a senha **e um código MFA quando o TOTP está inscrito**,
|
|
166
|
+
e manda o link pro novo endereço.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
# Trocar e-mail (logado) — pega o token no body em dev (modo C)
|
|
170
|
+
resp = await client.post(
|
|
171
|
+
"/auth/email-change/request",
|
|
172
|
+
json={"new_email": "nova@example.com", "current_password": "senha-atual"},
|
|
173
|
+
headers={"Authorization": f"Bearer {access_token}"},
|
|
174
|
+
)
|
|
175
|
+
confirm_url: str | None = resp.json()["confirm_url"] # None em produção (vai por e-mail)
|
|
176
|
+
|
|
177
|
+
# ...usuário abre o link; o front extrai o token e confirma:
|
|
178
|
+
await client.post("/auth/email-change/confirm", json={"token": token})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
!!! danger "Recuperação é sensível — ligue com cuidado"
|
|
182
|
+
`POST /auth/email-recovery/request` deixa quem tem a senha mover a
|
|
183
|
+
conta pra outro e-mail **sem** acessar a caixa antiga. Só é montado
|
|
184
|
+
com `AUTH_EMAIL_RECOVERY_ENABLED=True`. Sempre responde **202**
|
|
185
|
+
genérico (não enumera contas) e, se o TOTP estiver inscrito, exige um
|
|
186
|
+
`mfa_code` válido. Mantenha `AUTH_EMAIL_CHANGE_NOTIFY_OLD=True` pra o
|
|
187
|
+
endereço antigo sempre ser avisado.
|
|
188
|
+
|
|
189
|
+
!!! info "Onde o novo e-mail fica guardado"
|
|
190
|
+
O endereço pendente viaja na coluna `payload` do token
|
|
191
|
+
(`EMAIL_CHANGE`), não no `UserModel`. A confirmação relê o `payload`,
|
|
192
|
+
re-checa que o endereço ainda está livre (corrida entre pedido e
|
|
193
|
+
confirmação → **409**) e só então grava. Veja a nota de migração da
|
|
194
|
+
0.92.0.
|
|
195
|
+
|
|
147
196
|
### Renovando a sessão com o refresh token
|
|
148
197
|
|
|
149
198
|
O `access_token` é curto por design (`JWT_ACCESS_TTL_SECONDS`, 1 h por
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tempest-fastapi-sdk"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.92.0"
|
|
4
4
|
description = "Shared FastAPI building blocks: base schemas, ORM model, async repository, exceptions, pagination and settings — the conventions used across Tempest projects."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -84,6 +84,12 @@ from tempest_fastapi_sdk.auth import (
|
|
|
84
84
|
ActivationResponseSchema,
|
|
85
85
|
ActivationToken,
|
|
86
86
|
AuthCookieConfig,
|
|
87
|
+
EmailChangeConfirmSchema,
|
|
88
|
+
EmailChangeRequestSchema,
|
|
89
|
+
EmailChangeResponseSchema,
|
|
90
|
+
EmailChangeToken,
|
|
91
|
+
EmailRecoveryRequestSchema,
|
|
92
|
+
EmailVerificationToken,
|
|
87
93
|
LoginResponseSchema,
|
|
88
94
|
LoginSchema,
|
|
89
95
|
LogoutSchema,
|
|
@@ -361,7 +367,7 @@ from tempest_fastapi_sdk.websockets import (
|
|
|
361
367
|
make_websocket_router,
|
|
362
368
|
)
|
|
363
369
|
|
|
364
|
-
__version__: str = "0.
|
|
370
|
+
__version__: str = "0.92.0"
|
|
365
371
|
|
|
366
372
|
__all__: list[str] = [
|
|
367
373
|
"BASE_COLUMN_ORDER",
|
|
@@ -446,8 +452,14 @@ __all__: list[str] = [
|
|
|
446
452
|
"DestructiveMigrationError",
|
|
447
453
|
"DiskMetrics",
|
|
448
454
|
"DownloadUtils",
|
|
455
|
+
"EmailChangeConfirmSchema",
|
|
456
|
+
"EmailChangeRequestSchema",
|
|
457
|
+
"EmailChangeResponseSchema",
|
|
458
|
+
"EmailChangeToken",
|
|
459
|
+
"EmailRecoveryRequestSchema",
|
|
449
460
|
"EmailSettings",
|
|
450
461
|
"EmailUtils",
|
|
462
|
+
"EmailVerificationToken",
|
|
451
463
|
"EnvFeatureFlagBackend",
|
|
452
464
|
"EventStream",
|
|
453
465
|
"ExpiredTokenException",
|
{tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/__init__.py
RENAMED
|
@@ -31,6 +31,22 @@ from tempest_fastapi_sdk.auth.schemas import (
|
|
|
31
31
|
ActivationResponseSchema as ActivationResponseSchema,
|
|
32
32
|
)
|
|
33
33
|
from tempest_fastapi_sdk.auth.schemas import ActivationToken as ActivationToken
|
|
34
|
+
from tempest_fastapi_sdk.auth.schemas import (
|
|
35
|
+
EmailChangeConfirmSchema as EmailChangeConfirmSchema,
|
|
36
|
+
)
|
|
37
|
+
from tempest_fastapi_sdk.auth.schemas import (
|
|
38
|
+
EmailChangeRequestSchema as EmailChangeRequestSchema,
|
|
39
|
+
)
|
|
40
|
+
from tempest_fastapi_sdk.auth.schemas import (
|
|
41
|
+
EmailChangeResponseSchema as EmailChangeResponseSchema,
|
|
42
|
+
)
|
|
43
|
+
from tempest_fastapi_sdk.auth.schemas import EmailChangeToken as EmailChangeToken
|
|
44
|
+
from tempest_fastapi_sdk.auth.schemas import (
|
|
45
|
+
EmailRecoveryRequestSchema as EmailRecoveryRequestSchema,
|
|
46
|
+
)
|
|
47
|
+
from tempest_fastapi_sdk.auth.schemas import (
|
|
48
|
+
EmailVerificationToken as EmailVerificationToken,
|
|
49
|
+
)
|
|
34
50
|
from tempest_fastapi_sdk.auth.schemas import (
|
|
35
51
|
LoginResponseSchema as LoginResponseSchema,
|
|
36
52
|
)
|
|
@@ -78,6 +94,12 @@ __all__: list[str] = [
|
|
|
78
94
|
"ActivationResponseSchema",
|
|
79
95
|
"ActivationToken",
|
|
80
96
|
"AuthCookieConfig",
|
|
97
|
+
"EmailChangeConfirmSchema",
|
|
98
|
+
"EmailChangeRequestSchema",
|
|
99
|
+
"EmailChangeResponseSchema",
|
|
100
|
+
"EmailChangeToken",
|
|
101
|
+
"EmailRecoveryRequestSchema",
|
|
102
|
+
"EmailVerificationToken",
|
|
81
103
|
"LoginResponseSchema",
|
|
82
104
|
"LoginSchema",
|
|
83
105
|
"LogoutSchema",
|
{tempest_fastapi_sdk-0.91.0 → tempest_fastapi_sdk-0.92.0}/tempest_fastapi_sdk/auth/locale.py
RENAMED
|
@@ -142,12 +142,30 @@ AUTH_EMAIL_MESSAGES: dict[str, dict[str, str]] = {
|
|
|
142
142
|
"activation_body": "Abra este link para ativar sua conta: {url}",
|
|
143
143
|
"password_reset_subject": "Redefina sua senha",
|
|
144
144
|
"password_reset_body": "Abra este link para redefinir sua senha: {url}",
|
|
145
|
+
"email_change_subject": "Confirme seu novo e-mail",
|
|
146
|
+
"email_change_body": "Abra este link para confirmar seu novo e-mail: {url}",
|
|
147
|
+
"email_verification_subject": "Verifique seu e-mail",
|
|
148
|
+
"email_verification_body": "Abra este link para verificar seu e-mail: {url}",
|
|
149
|
+
"email_changed_notice_subject": "Seu e-mail foi alterado",
|
|
150
|
+
"email_changed_notice_body": (
|
|
151
|
+
"O e-mail da sua conta foi alterado para {new_email}. "
|
|
152
|
+
"Se não foi você, fale com o suporte imediatamente."
|
|
153
|
+
),
|
|
145
154
|
},
|
|
146
155
|
"en-US": {
|
|
147
156
|
"activation_subject": "Activate your account",
|
|
148
157
|
"activation_body": "Open this link to activate your account: {url}",
|
|
149
158
|
"password_reset_subject": "Reset your password",
|
|
150
159
|
"password_reset_body": "Open this link to reset your password: {url}",
|
|
160
|
+
"email_change_subject": "Confirm your new email",
|
|
161
|
+
"email_change_body": "Open this link to confirm your new email: {url}",
|
|
162
|
+
"email_verification_subject": "Verify your email",
|
|
163
|
+
"email_verification_body": "Open this link to verify your email: {url}",
|
|
164
|
+
"email_changed_notice_subject": "Your email was changed",
|
|
165
|
+
"email_changed_notice_body": (
|
|
166
|
+
"Your account email was changed to {new_email}. "
|
|
167
|
+
"If this wasn't you, contact support immediately."
|
|
168
|
+
),
|
|
151
169
|
},
|
|
152
170
|
}
|
|
153
171
|
|
|
@@ -186,12 +204,14 @@ def auth_email_message(locale: str, key: str) -> str:
|
|
|
186
204
|
Args:
|
|
187
205
|
locale (str): A canonical supported locale. Unknown locales fall
|
|
188
206
|
back to :data:`DEFAULT_AUTH_LOCALE`.
|
|
189
|
-
key (str): One of ``
|
|
190
|
-
``
|
|
207
|
+
key (str): One of the ``*_subject`` / ``*_body`` keys —
|
|
208
|
+
``activation``, ``password_reset``, ``email_change``,
|
|
209
|
+
``email_verification`` and ``email_changed_notice``.
|
|
191
210
|
|
|
192
211
|
Returns:
|
|
193
|
-
str: The localized string.
|
|
194
|
-
``{url}``
|
|
212
|
+
str: The localized string. ``*_body`` strings still contain a
|
|
213
|
+
placeholder (``{url}``, or ``{new_email}`` for
|
|
214
|
+
``email_changed_notice_body``) for the caller to ``.format(...)``.
|
|
195
215
|
"""
|
|
196
216
|
table = AUTH_EMAIL_MESSAGES.get(locale, AUTH_EMAIL_MESSAGES[DEFAULT_AUTH_LOCALE])
|
|
197
217
|
return table[key]
|