tempest-fastapi-sdk 0.76.0__tar.gz → 0.78.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.76.0 → tempest_fastapi_sdk-0.78.0}/CHANGELOG.md +30 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/PKG-INFO +6 -4
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/README.md +5 -3
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/architecture.en.md +2 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/architecture.md +2 -0
- tempest_fastapi_sdk-0.78.0/docs/recipes/fields.en.md +88 -0
- tempest_fastapi_sdk-0.78.0/docs/recipes/fields.md +88 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/mkdocs.yml +1 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/pyproject.toml +1 -1
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/__init__.py +29 -1
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/controllers/base.py +13 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/services/base.py +34 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/__init__.py +30 -0
- tempest_fastapi_sdk-0.78.0/tempest_fastapi_sdk/utils/fields.py +116 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/controllers/test_base.py +10 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/services/test_base.py +35 -0
- tempest_fastapi_sdk-0.78.0/tests/utils/test_fields.py +140 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/uv.lock +1 -1
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/.github/workflows/ci.yml +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/.github/workflows/docs.yml +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/.gitignore +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/.python-version +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/CLAUDE.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/Makefile +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/changelog.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/changelog.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/contributing.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/contributing.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/index.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/index.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/installation.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/installation.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/index.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/index.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/api.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/api.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/business-rules.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/business-rules.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/domain.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/domain.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/flows.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/flows.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/index.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/learning/marketplace/index.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/migration.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/migration.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/admin.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/admin.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/audit-trail.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/audit-trail.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/auth-flow.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/auth-flow.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/br-helpers.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/br-helpers.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/cache.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/cache.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/cli.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/cli.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/database.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/database.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/deploy-safety.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/deploy-safety.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/downloads.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/downloads.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/email.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/email.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/feature-flags.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/feature-flags.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/http-client.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/http-client.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/http.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/http.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/idempotency.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/idempotency.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/index.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/index.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/logging.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/logging.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/metrics.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/metrics.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/mfa.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/mfa.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/multi-tenant.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/multi-tenant.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/observability.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/observability.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/offline-sync.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/offline-sync.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/outbox.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/outbox.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/queue-tasks.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/queue-tasks.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/realtime.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/realtime.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/refresh-tokens.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/refresh-tokens.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/security.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/security.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/sessions.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/sessions.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/storage.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/storage.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/stored-files.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/stored-files.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/testing.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/testing.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/typing.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/typing.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/uploads.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/uploads.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/utilities.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/utilities.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/webpush.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/webpush.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/websocket.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/recipes/websocket.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/reference.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/reference.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/roadmap.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/roadmap.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/tutorial.en.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/docs/tutorial.md +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/mkdocs_hooks/llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/scripts/extract_recipe.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/auth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/config.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/discovery.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/forms.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/session.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/site.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/static/admin.css +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/detail.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/form.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/list.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/logs.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/templates/mfa.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/admin/theme.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/dependencies/auth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/graceful.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/server.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/static.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/tracing.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/guards.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/locale.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/schemas.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/service.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/activation.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cache/invalidation.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/Dockerfile.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/dockerignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/resources.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/config.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/db.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/main.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/new.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/secrets.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/src_layers.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/cli/user.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/core/context.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/core/enums.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/core/logging.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/core/typed.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/audit.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/backup.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/connection.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/mixins.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/outbox.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/repository.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/slow_query.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/tenant.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/user_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/user_recovery_code_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/user_refresh_token_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/db/user_token_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/i18n.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/flags/backends.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/flags/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/flags/service.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/py.typed +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/services/file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/settings/base.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/settings/mixins.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/sse/event_stream.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/storage/minio_client.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/testing/database.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/data/br_locations.json +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/download.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/email.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/locations.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/log.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/password.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/totp.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/upload.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_auth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_discovery.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_forms.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_logs_nav.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_site.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_theme.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/admin/test_user_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_body_size.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_cookies.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_cors.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_csrf.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_dependencies_auth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_graceful.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_handlers.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_health_router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_idempotency.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_jwt_dependency.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_logs_router.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_oauth.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_prometheus.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_rate_limit_extras.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_request_id_middleware.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_role_dependency.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_server.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_static.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/api/test_webhooks_rsa.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_guards.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_locale.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_refresh.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_refresh_db.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/auth/test_service.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cache/test_decorator.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cache/test_invalidation.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cache/test_redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_config.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_db.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_db_seed.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_lint_strictness.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_main.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_secrets.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/cli/test_user.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/conftest.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/core/test_context.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/core/test_enums.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/core/test_logging.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/core/test_typed.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_audit.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_backup.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_bulk_ops.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_connection.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_migrations.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_model.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_outbox.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_repository.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_safe_upgrade.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_slow_query.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/db/test_tenant.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/exceptions/test_exceptions.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/exceptions/test_i18n.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/flags/test_flags.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/queue/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/test_base.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/test_cursor_pagination.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/test_link_headers.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/test_pagination.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/schemas/test_response.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/services/test_file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/sessions/test_sessions.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/settings/test_base.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/settings/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/sse/test_event_stream.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/storage/test_minio_client.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/tasks/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/tasks/test_scheduler.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/testing/test_database.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_client_ip.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_datetime.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_dict.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_download.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_email.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_http_client.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_jwt.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_lazy_extras.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_locations.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_log.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_metrics.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_password.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_regex.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_throttle.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/utils/test_upload.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/webpush/test_dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/webpush/test_schemas.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tests/websockets/test_hub_and_router.py +0 -0
|
@@ -5,6 +5,36 @@ 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.78.0] — 2026-06-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`BaseService.update` (and `BaseController.update`).** The service
|
|
13
|
+
skeleton now ships a generic update method: fetch by primary key, copy
|
|
14
|
+
the fields present in the payload (`data.to_dict()`, which drops unset
|
|
15
|
+
and ``None`` values) onto the instance, persist via
|
|
16
|
+
``repository.update`` and return the mapped response. Because unset
|
|
17
|
+
fields are skipped, the same method serves full (PUT) and partial
|
|
18
|
+
(PATCH) updates. ``BaseController.update`` forwards to it, matching the
|
|
19
|
+
existing pass-through layer. Override either when an update needs
|
|
20
|
+
orchestration.
|
|
21
|
+
|
|
22
|
+
## [0.77.0] — 2026-06-27
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **Generic validated field types (`tempest_fastapi_sdk.utils.fields`).**
|
|
27
|
+
A base set of `Annotated` Pydantic types that bake a validation rule
|
|
28
|
+
into the type, following the `*Field` convention (so the schema reads as
|
|
29
|
+
what it is instead of repeating `Field(gt=0, ...)`): integers
|
|
30
|
+
`PositiveIntField`, `NonNegativeIntField`, `CentsField` (money in minor
|
|
31
|
+
units), `PortField`; floats `PositiveFloatField`, `NonNegativeFloatField`,
|
|
32
|
+
`PercentField` (0..100), `RatioField` (0..1), `LatitudeField`,
|
|
33
|
+
`LongitudeField`; `PriceField` (non-negative `Decimal`, 2 places); and
|
|
34
|
+
strings `NonEmptyStrField` (trim + non-empty), `SlugField`,
|
|
35
|
+
`HexColorField`. Exported from `tempest_fastapi_sdk` and
|
|
36
|
+
`tempest_fastapi_sdk.utils`.
|
|
37
|
+
|
|
8
38
|
## [0.76.0] — 2026-06-27
|
|
9
39
|
|
|
10
40
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempest-fastapi-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.78.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
|
|
@@ -259,7 +259,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
259
259
|
| `tempest_fastapi_sdk.utils.http_client` *(extra: `[http]`)* | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, `REQUEST_ID_HEADER` — typed httpx wrapper |
|
|
260
260
|
| `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
|
|
261
261
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
262
|
-
| `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]`)*, 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`) |
|
|
262
|
+
| `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`) |
|
|
263
263
|
| `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` |
|
|
264
264
|
|
|
265
265
|
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` and `tempest_fastapi_sdk.tasks` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
@@ -714,7 +714,7 @@ The highlighted block (under the divider comment) is what you typically add per
|
|
|
714
714
|
|
|
715
715
|
The service is where business rules live. It calls one or more repositories and never touches HTTP or SQLAlchemy types directly.
|
|
716
716
|
|
|
717
|
-
Inherit from `BaseService[RepositoryT, ResponseT]`. Doing so gives you `get_by_id`, `get_or_none`, `list`, `paginate`, `count`, `exists` and `delete` for free — every one is already wired to `repository.map_to_response` (sync or async). Override only the methods that need domain logic; add new ones for use cases the base doesn't cover (signup, password reset, etc.):
|
|
717
|
+
Inherit from `BaseService[RepositoryT, ResponseT]`. Doing so gives you `get_by_id`, `get_or_none`, `list`, `paginate`, `count`, `exists`, `update` and `delete` for free — every one is already wired to `repository.map_to_response` (sync or async). Override only the methods that need domain logic; add new ones for use cases the base doesn't cover (signup, password reset, etc.):
|
|
718
718
|
|
|
719
719
|
```python
|
|
720
720
|
# src/services/user.py
|
|
@@ -811,7 +811,7 @@ class UserService(BaseService[UserRepository, UserResponseSchema]):
|
|
|
811
811
|
|
|
812
812
|
Even when there's no orchestration to do, `controllers/` exists as a **thin pass-through** so the import graph stays uniform across services. The day a use case needs to coordinate two services (or fan out to a queue), the controller is already there.
|
|
813
813
|
|
|
814
|
-
Inherit from `BaseController[ServiceT, ResponseT]`. The base forwards `get_by_id`, `list`, `paginate`, `count` and `delete` to the service for you — you only declare methods that add cross-service coordination or that don't exist on the service (custom use cases like `signup`):
|
|
814
|
+
Inherit from `BaseController[ServiceT, ResponseT]`. The base forwards `get_by_id`, `list`, `paginate`, `count`, `update` and `delete` to the service for you — you only declare methods that add cross-service coordination or that don't exist on the service (custom use cases like `signup`):
|
|
815
815
|
|
|
816
816
|
```python
|
|
817
817
|
# src/controllers/user.py
|
|
@@ -2136,6 +2136,7 @@ What you inherit by subclassing `BaseService[RepositoryT, ResponseT]`:
|
|
|
2136
2136
|
| `paginate(filters=None, order_by=None, page=1, page_size=20, ascending=True)` | `dict` with mapped `items` + `total`/`page`/`size`/`pages`. | Offset pagination via `repository.paginate`. |
|
|
2137
2137
|
| `count(filters=None)` | `int` | Pass-through to `repository.count`. |
|
|
2138
2138
|
| `exists(filters)` | `bool` | Pass-through to `repository.exists`. |
|
|
2139
|
+
| `update(id, data)` | `ResponseT` | Fetch by id, copy the fields present in `data` (a `BaseSchema`) onto the row, persist, map. `to_dict()` drops unset/`None`, so it serves PUT and PATCH alike. |
|
|
2139
2140
|
| `delete(id)` | `None` | Hard delete via `repository.delete`. |
|
|
2140
2141
|
|
|
2141
2142
|
`map_to_response` is `await`-ed when it returns a coroutine, so async mappers work transparently — no method override needed.
|
|
@@ -2148,6 +2149,7 @@ What you inherit by subclassing `BaseController[ServiceT, ResponseT]`:
|
|
|
2148
2149
|
| `list(filters, order_by, ascending)` | `service.list` | Same. |
|
|
2149
2150
|
| `paginate(filters, order_by, page, page_size, ascending)` | `service.paginate` | Same. |
|
|
2150
2151
|
| `count(filters)` | `service.count` | Same. |
|
|
2152
|
+
| `update(id, data)` | `service.update` | Same. |
|
|
2151
2153
|
| `delete(id)` | `service.delete` | Same. |
|
|
2152
2154
|
|
|
2153
2155
|
When a use case needs domain rules, override the inherited method in the service. When a use case needs to coordinate more than one service, override the inherited method (or add a new one) in the controller. The router never grows — it only depends on the controller.
|
|
@@ -156,7 +156,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
156
156
|
| `tempest_fastapi_sdk.utils.http_client` *(extra: `[http]`)* | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, `REQUEST_ID_HEADER` — typed httpx wrapper |
|
|
157
157
|
| `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
|
|
158
158
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
159
|
-
| `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]`)*, 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`) |
|
|
159
|
+
| `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`) |
|
|
160
160
|
| `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` |
|
|
161
161
|
|
|
162
162
|
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` and `tempest_fastapi_sdk.tasks` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
@@ -611,7 +611,7 @@ The highlighted block (under the divider comment) is what you typically add per
|
|
|
611
611
|
|
|
612
612
|
The service is where business rules live. It calls one or more repositories and never touches HTTP or SQLAlchemy types directly.
|
|
613
613
|
|
|
614
|
-
Inherit from `BaseService[RepositoryT, ResponseT]`. Doing so gives you `get_by_id`, `get_or_none`, `list`, `paginate`, `count`, `exists` and `delete` for free — every one is already wired to `repository.map_to_response` (sync or async). Override only the methods that need domain logic; add new ones for use cases the base doesn't cover (signup, password reset, etc.):
|
|
614
|
+
Inherit from `BaseService[RepositoryT, ResponseT]`. Doing so gives you `get_by_id`, `get_or_none`, `list`, `paginate`, `count`, `exists`, `update` and `delete` for free — every one is already wired to `repository.map_to_response` (sync or async). Override only the methods that need domain logic; add new ones for use cases the base doesn't cover (signup, password reset, etc.):
|
|
615
615
|
|
|
616
616
|
```python
|
|
617
617
|
# src/services/user.py
|
|
@@ -708,7 +708,7 @@ class UserService(BaseService[UserRepository, UserResponseSchema]):
|
|
|
708
708
|
|
|
709
709
|
Even when there's no orchestration to do, `controllers/` exists as a **thin pass-through** so the import graph stays uniform across services. The day a use case needs to coordinate two services (or fan out to a queue), the controller is already there.
|
|
710
710
|
|
|
711
|
-
Inherit from `BaseController[ServiceT, ResponseT]`. The base forwards `get_by_id`, `list`, `paginate`, `count` and `delete` to the service for you — you only declare methods that add cross-service coordination or that don't exist on the service (custom use cases like `signup`):
|
|
711
|
+
Inherit from `BaseController[ServiceT, ResponseT]`. The base forwards `get_by_id`, `list`, `paginate`, `count`, `update` and `delete` to the service for you — you only declare methods that add cross-service coordination or that don't exist on the service (custom use cases like `signup`):
|
|
712
712
|
|
|
713
713
|
```python
|
|
714
714
|
# src/controllers/user.py
|
|
@@ -2033,6 +2033,7 @@ What you inherit by subclassing `BaseService[RepositoryT, ResponseT]`:
|
|
|
2033
2033
|
| `paginate(filters=None, order_by=None, page=1, page_size=20, ascending=True)` | `dict` with mapped `items` + `total`/`page`/`size`/`pages`. | Offset pagination via `repository.paginate`. |
|
|
2034
2034
|
| `count(filters=None)` | `int` | Pass-through to `repository.count`. |
|
|
2035
2035
|
| `exists(filters)` | `bool` | Pass-through to `repository.exists`. |
|
|
2036
|
+
| `update(id, data)` | `ResponseT` | Fetch by id, copy the fields present in `data` (a `BaseSchema`) onto the row, persist, map. `to_dict()` drops unset/`None`, so it serves PUT and PATCH alike. |
|
|
2036
2037
|
| `delete(id)` | `None` | Hard delete via `repository.delete`. |
|
|
2037
2038
|
|
|
2038
2039
|
`map_to_response` is `await`-ed when it returns a coroutine, so async mappers work transparently — no method override needed.
|
|
@@ -2045,6 +2046,7 @@ What you inherit by subclassing `BaseController[ServiceT, ResponseT]`:
|
|
|
2045
2046
|
| `list(filters, order_by, ascending)` | `service.list` | Same. |
|
|
2046
2047
|
| `paginate(filters, order_by, page, page_size, ascending)` | `service.paginate` | Same. |
|
|
2047
2048
|
| `count(filters)` | `service.count` | Same. |
|
|
2049
|
+
| `update(id, data)` | `service.update` | Same. |
|
|
2048
2050
|
| `delete(id)` | `service.delete` | Same. |
|
|
2049
2051
|
|
|
2050
2052
|
When a use case needs domain rules, override the inherited method in the service. When a use case needs to coordinate more than one service, override the inherited method (or add a new one) in the controller. The router never grows — it only depends on the controller.
|
|
@@ -147,6 +147,7 @@ What you inherit by subclassing `BaseService[RepositoryT, ResponseT]`:
|
|
|
147
147
|
| `paginate(filters=None, order_by=None, page=1, page_size=20, ascending=True)` | `dict` with mapped `items` + `total`/`page`/`page_size`/`pages`. | Offset pagination via `repository.paginate`. |
|
|
148
148
|
| `count(filters=None)` | `int` | Pass-through to `repository.count`. |
|
|
149
149
|
| `exists(filters)` | `bool` | Pass-through to `repository.exists`. |
|
|
150
|
+
| `update(id, data)` | `ResponseT` | Fetch by id, copy the fields present in `data` (a `BaseSchema`) onto the row, persist, map. `to_dict()` drops unset/`None`, so it serves PUT and PATCH. |
|
|
150
151
|
| `delete(id)` | `None` | Hard delete via `repository.delete`. |
|
|
151
152
|
|
|
152
153
|
`map_to_response` is `await`-ed when it returns a coroutine, so async mappers work transparently — no method override needed.
|
|
@@ -159,6 +160,7 @@ What you inherit by subclassing `BaseController[ServiceT, ResponseT]`:
|
|
|
159
160
|
| `list(filters, order_by, ascending)` | `service.list` | Same. |
|
|
160
161
|
| `paginate(filters, order_by, page, page_size, ascending)` | `service.paginate` | Same. |
|
|
161
162
|
| `count(filters)` | `service.count` | Same. |
|
|
163
|
+
| `update(id, data)` | `service.update` | Same. |
|
|
162
164
|
| `delete(id)` | `service.delete` | Same. |
|
|
163
165
|
|
|
164
166
|
When a use case needs domain rules, override the inherited method in the service. When a use case needs to coordinate more than one service, override the inherited method (or add a new one) in the controller. The router never grows — it only depends on the controller.
|
|
@@ -147,6 +147,7 @@ O que você herda ao subclassear `BaseService[RepositoryT, ResponseT]`:
|
|
|
147
147
|
| `paginate(filters=None, order_by=None, page=1, page_size=20, ascending=True)` | `dict` com `items` mapeados + `total`/`page`/`page_size`/`pages`. | Paginação por offset via `repository.paginate`. |
|
|
148
148
|
| `count(filters=None)` | `int` | Pass-through para `repository.count`. |
|
|
149
149
|
| `exists(filters)` | `bool` | Pass-through para `repository.exists`. |
|
|
150
|
+
| `update(id, data)` | `ResponseT` | Busca por id, copia os campos presentes em `data` (um `BaseSchema`) na instância, persiste e mapeia. `to_dict()` descarta unset/`None`, então serve PUT e PATCH. |
|
|
150
151
|
| `delete(id)` | `None` | Hard delete via `repository.delete`. |
|
|
151
152
|
|
|
152
153
|
`map_to_response` é aguardado com `await` quando retorna uma coroutine, então mappers async funcionam de forma transparente — sem precisar sobrescrever o método.
|
|
@@ -159,6 +160,7 @@ O que você herda ao subclassear `BaseController[ServiceT, ResponseT]`:
|
|
|
159
160
|
| `list(filters, order_by, ascending)` | `service.list` | Igual. |
|
|
160
161
|
| `paginate(filters, order_by, page, page_size, ascending)` | `service.paginate` | Igual. |
|
|
161
162
|
| `count(filters)` | `service.count` | Igual. |
|
|
163
|
+
| `update(id, data)` | `service.update` | Igual. |
|
|
162
164
|
| `delete(id)` | `service.delete` | Igual. |
|
|
163
165
|
|
|
164
166
|
Quando um caso de uso precisa de regras de domínio, sobrescreva o método herdado no service. Quando um caso de uso precisa coordenar mais de um service, sobrescreva o método herdado (ou adicione um novo) no controller. O router nunca cresce — ele só depende do controller.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Validated fields (ready-made types)
|
|
2
|
+
|
|
3
|
+
Instead of repeating `Field(gt=0, ...)` on every schema, the SDK ships
|
|
4
|
+
`Annotated` types with the validation rule baked in — the field becomes
|
|
5
|
+
**self-describing**. They follow the same `*Field` convention as the BR
|
|
6
|
+
fields (`CPFField`, `UFField`, ...): anything ending in `Field` is a
|
|
7
|
+
ready-to-use schema field type. Invalid values raise `ValidationError` ->
|
|
8
|
+
HTTP 422 via the SDK exception handler.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
12
|
+
from tempest_fastapi_sdk.utils import CentsField, PercentField, SlugField
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProductCreateSchema(BaseSchema):
|
|
16
|
+
slug: SlugField # lowercase kebab-case
|
|
17
|
+
price_cents: CentsField # int >= 0 (money in cents)
|
|
18
|
+
discount: PercentField # float in [0, 100]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Integers
|
|
22
|
+
|
|
23
|
+
| Type | Rule | Use |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `PositiveIntField` | `> 0` | quantities, counts, 1-based ids |
|
|
26
|
+
| `NonNegativeIntField` | `>= 0` | counters that reset to zero |
|
|
27
|
+
| `CentsField` | `>= 0` | money in minor units (cents) |
|
|
28
|
+
| `PortField` | `1..65535` | TCP/UDP port |
|
|
29
|
+
|
|
30
|
+
!!! tip "Money in cents"
|
|
31
|
+
Store monetary values as an **integer of cents** (`CentsField`) to
|
|
32
|
+
dodge binary float rounding. Divide by 100 only at the presentation
|
|
33
|
+
edge. When the contract requires an exact decimal (e.g. a gateway
|
|
34
|
+
payload), use `PriceField`.
|
|
35
|
+
|
|
36
|
+
## Floats
|
|
37
|
+
|
|
38
|
+
| Type | Rule |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `PositiveFloatField` | `> 0` |
|
|
41
|
+
| `NonNegativeFloatField` | `>= 0` |
|
|
42
|
+
| `PercentField` | `0..100` |
|
|
43
|
+
| `RatioField` | `0..1` (fractions/probabilities) |
|
|
44
|
+
| `LatitudeField` | `-90..90` |
|
|
45
|
+
| `LongitudeField` | `-180..180` |
|
|
46
|
+
|
|
47
|
+
## Decimals
|
|
48
|
+
|
|
49
|
+
`PriceField` is a non-negative `Decimal` with 2 places:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
53
|
+
from tempest_fastapi_sdk.utils import PriceField
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class InvoiceSchema(BaseSchema):
|
|
57
|
+
total: PriceField # "9.99" -> Decimal("9.99"); "1.999" and "-1" rejected
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Strings
|
|
61
|
+
|
|
62
|
+
| Type | Rule |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `NonEmptyStrField` | trims whitespace and rejects empty (whitespace-only too) |
|
|
65
|
+
| `SlugField` | lowercase kebab-case (`my-post-1`) |
|
|
66
|
+
| `HexColorField` | CSS hex color (`#fff` or `#abc123`) |
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
70
|
+
from tempest_fastapi_sdk.utils import HexColorField, NonEmptyStrField, SlugField
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class CategorySchema(BaseSchema):
|
|
74
|
+
name: NonEmptyStrField # " Drinks " -> "Drinks"; " " rejected
|
|
75
|
+
slug: SlugField
|
|
76
|
+
color: HexColorField
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Recap
|
|
80
|
+
|
|
81
|
+
- Everything is `Annotated[..., rule]` with a `*Field` suffix —
|
|
82
|
+
self-describing, no repeated `Field(...)` in the schema.
|
|
83
|
+
- Integers: `PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`.
|
|
84
|
+
- Floats: `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`,
|
|
85
|
+
`RatioField`, `LatitudeField`, `LongitudeField`.
|
|
86
|
+
- Decimal: `PriceField` (2 places, `>= 0`).
|
|
87
|
+
- Strings: `NonEmptyStrField`, `SlugField`, `HexColorField`.
|
|
88
|
+
- Money: prefer `CentsField` (integer) for storage; `PriceField` for a decimal contract.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Campos validados (tipos prontos)
|
|
2
|
+
|
|
3
|
+
Em vez de repetir `Field(gt=0, ...)` em cada schema, o SDK traz tipos
|
|
4
|
+
`Annotated` com a regra de validação embutida — o campo passa a se
|
|
5
|
+
**autodescrever**. Seguem a mesma convenção `*Field` dos campos BR
|
|
6
|
+
(`CPFField`, `UFField`, ...): tudo que termina em `Field` é um tipo de
|
|
7
|
+
campo pronto pra schema. Valor inválido vira `ValidationError` → HTTP 422
|
|
8
|
+
pelo handler do SDK.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
12
|
+
from tempest_fastapi_sdk.utils import CentsField, PercentField, SlugField
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProductCreateSchema(BaseSchema):
|
|
16
|
+
slug: SlugField # kebab-case minúsculo
|
|
17
|
+
price_cents: CentsField # int >= 0 (dinheiro em centavos)
|
|
18
|
+
discount: PercentField # float em [0, 100]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Inteiros
|
|
22
|
+
|
|
23
|
+
| Tipo | Regra | Uso |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `PositiveIntField` | `> 0` | quantidades, contagens, ids 1-based |
|
|
26
|
+
| `NonNegativeIntField` | `>= 0` | contadores que zeram |
|
|
27
|
+
| `CentsField` | `>= 0` | dinheiro em unidades menores (centavos) |
|
|
28
|
+
| `PortField` | `1..65535` | porta TCP/UDP |
|
|
29
|
+
|
|
30
|
+
!!! tip "Dinheiro em centavos"
|
|
31
|
+
Guarde valores monetários como **inteiro de centavos** (`CentsField`)
|
|
32
|
+
pra fugir do arredondamento de float binário. Divida por 100 só na
|
|
33
|
+
borda de apresentação. Quando o contrato exige decimal exato (ex.:
|
|
34
|
+
payload de gateway), use `PriceField`.
|
|
35
|
+
|
|
36
|
+
## Floats
|
|
37
|
+
|
|
38
|
+
| Tipo | Regra |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `PositiveFloatField` | `> 0` |
|
|
41
|
+
| `NonNegativeFloatField` | `>= 0` |
|
|
42
|
+
| `PercentField` | `0..100` |
|
|
43
|
+
| `RatioField` | `0..1` (frações/probabilidades) |
|
|
44
|
+
| `LatitudeField` | `-90..90` |
|
|
45
|
+
| `LongitudeField` | `-180..180` |
|
|
46
|
+
|
|
47
|
+
## Decimais
|
|
48
|
+
|
|
49
|
+
`PriceField` é um `Decimal` não-negativo com 2 casas:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
53
|
+
from tempest_fastapi_sdk.utils import PriceField
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class InvoiceSchema(BaseSchema):
|
|
57
|
+
total: PriceField # "9.99" -> Decimal("9.99"); "1.999" e "-1" rejeitados
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Strings
|
|
61
|
+
|
|
62
|
+
| Tipo | Regra |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `NonEmptyStrField` | apara espaços e rejeita vazio (só-espaço também) |
|
|
65
|
+
| `SlugField` | kebab-case minúsculo (`meu-post-1`) |
|
|
66
|
+
| `HexColorField` | cor hex CSS (`#fff` ou `#abc123`) |
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from tempest_fastapi_sdk import BaseSchema
|
|
70
|
+
from tempest_fastapi_sdk.utils import HexColorField, NonEmptyStrField, SlugField
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class CategorySchema(BaseSchema):
|
|
74
|
+
name: NonEmptyStrField # " Bebidas " -> "Bebidas"; " " rejeitado
|
|
75
|
+
slug: SlugField
|
|
76
|
+
color: HexColorField
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Recap
|
|
80
|
+
|
|
81
|
+
- Tudo `Annotated[..., regra]`, com sufixo `*Field` — autodescritivo,
|
|
82
|
+
sem repetir `Field(...)` no schema.
|
|
83
|
+
- Inteiros: `PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`.
|
|
84
|
+
- Floats: `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`,
|
|
85
|
+
`RatioField`, `LatitudeField`, `LongitudeField`.
|
|
86
|
+
- Decimal: `PriceField` (2 casas, `>= 0`).
|
|
87
|
+
- Strings: `NonEmptyStrField`, `SlugField`, `HexColorField`.
|
|
88
|
+
- Dinheiro: prefira `CentsField` (inteiro) pra guardar; `PriceField` no contrato decimal.
|
|
@@ -219,6 +219,7 @@ nav:
|
|
|
219
219
|
- CLI: recipes/cli.md
|
|
220
220
|
- "Deploy seguro (migrations + shutdown)": recipes/deploy-safety.md
|
|
221
221
|
- Downloads: recipes/downloads.md
|
|
222
|
+
- "Campos validados (tipos prontos)": recipes/fields.md
|
|
222
223
|
- Email transacional: recipes/email.md
|
|
223
224
|
- Feature flags: recipes/feature-flags.md
|
|
224
225
|
- Fila e Tarefas: recipes/queue-tasks.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tempest-fastapi-sdk"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.78.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"
|
|
@@ -245,6 +245,7 @@ from tempest_fastapi_sdk.utils import (
|
|
|
245
245
|
REQUEST_ID_HEADER,
|
|
246
246
|
UF,
|
|
247
247
|
AttemptThrottle,
|
|
248
|
+
CentsField,
|
|
248
249
|
CEPField,
|
|
249
250
|
ChoiceBR,
|
|
250
251
|
CircuitOpenError,
|
|
@@ -259,18 +260,31 @@ from tempest_fastapi_sdk.utils import (
|
|
|
259
260
|
DownloadUtils,
|
|
260
261
|
EmailUtils,
|
|
261
262
|
GPUMetrics,
|
|
263
|
+
HexColorField,
|
|
262
264
|
HTTPClient,
|
|
263
265
|
JWTUtils,
|
|
266
|
+
LatitudeField,
|
|
264
267
|
LocalUploadStorage,
|
|
265
268
|
LogUtils,
|
|
269
|
+
LongitudeField,
|
|
266
270
|
MemoryMetrics,
|
|
267
271
|
MetricsUtils,
|
|
268
272
|
MinIOUploadStorage,
|
|
273
|
+
NonEmptyStrField,
|
|
274
|
+
NonNegativeFloatField,
|
|
275
|
+
NonNegativeIntField,
|
|
269
276
|
PasswordUtils,
|
|
277
|
+
PercentField,
|
|
270
278
|
PhoneBR,
|
|
271
279
|
PhoneBRField,
|
|
280
|
+
PortField,
|
|
281
|
+
PositiveFloatField,
|
|
282
|
+
PositiveIntField,
|
|
283
|
+
PriceField,
|
|
284
|
+
RatioField,
|
|
272
285
|
Region,
|
|
273
286
|
RetryPolicy,
|
|
287
|
+
SlugField,
|
|
274
288
|
StateBR,
|
|
275
289
|
SystemMetrics,
|
|
276
290
|
ThrottleBackend,
|
|
@@ -328,7 +342,7 @@ from tempest_fastapi_sdk.websockets import (
|
|
|
328
342
|
make_websocket_router,
|
|
329
343
|
)
|
|
330
344
|
|
|
331
|
-
__version__: str = "0.
|
|
345
|
+
__version__: str = "0.78.0"
|
|
332
346
|
|
|
333
347
|
__all__: list[str] = [
|
|
334
348
|
"BASE_COLUMN_ORDER",
|
|
@@ -394,6 +408,7 @@ __all__: list[str] = [
|
|
|
394
408
|
"CPUMetrics",
|
|
395
409
|
"CSRFMiddleware",
|
|
396
410
|
"CachedResponse",
|
|
411
|
+
"CentsField",
|
|
397
412
|
"ChoiceBR",
|
|
398
413
|
"CircuitOpenError",
|
|
399
414
|
"CityBR",
|
|
@@ -424,6 +439,7 @@ __all__: list[str] = [
|
|
|
424
439
|
"HTTPClient",
|
|
425
440
|
"HardenedStaticFiles",
|
|
426
441
|
"HealthCheck",
|
|
442
|
+
"HexColorField",
|
|
427
443
|
"IdempotencyMiddleware",
|
|
428
444
|
"IdempotencyStore",
|
|
429
445
|
"InvalidFileTypeException",
|
|
@@ -431,6 +447,7 @@ __all__: list[str] = [
|
|
|
431
447
|
"JSONFormatter",
|
|
432
448
|
"JWTSettings",
|
|
433
449
|
"JWTUtils",
|
|
450
|
+
"LatitudeField",
|
|
434
451
|
"LocalUploadStorage",
|
|
435
452
|
"LogEntrySchema",
|
|
436
453
|
"LogSettings",
|
|
@@ -439,6 +456,7 @@ __all__: list[str] = [
|
|
|
439
456
|
"LoginResponseSchema",
|
|
440
457
|
"LoginSchema",
|
|
441
458
|
"LogoutSchema",
|
|
459
|
+
"LongitudeField",
|
|
442
460
|
"MFAConfirmSchema",
|
|
443
461
|
"MFADisableSchema",
|
|
444
462
|
"MFAEnrollResponseSchema",
|
|
@@ -453,6 +471,9 @@ __all__: list[str] = [
|
|
|
453
471
|
"MetricsUtils",
|
|
454
472
|
"MinIOSettings",
|
|
455
473
|
"MinIOUploadStorage",
|
|
474
|
+
"NonEmptyStrField",
|
|
475
|
+
"NonNegativeFloatField",
|
|
476
|
+
"NonNegativeIntField",
|
|
456
477
|
"NotFoundException",
|
|
457
478
|
"OAuthError",
|
|
458
479
|
"OAuthTokens",
|
|
@@ -468,14 +489,20 @@ __all__: list[str] = [
|
|
|
468
489
|
"PasswordResetResponseSchema",
|
|
469
490
|
"PasswordResetToken",
|
|
470
491
|
"PasswordUtils",
|
|
492
|
+
"PercentField",
|
|
471
493
|
"PhoneBR",
|
|
472
494
|
"PhoneBRField",
|
|
495
|
+
"PortField",
|
|
496
|
+
"PositiveFloatField",
|
|
497
|
+
"PositiveIntField",
|
|
498
|
+
"PriceField",
|
|
473
499
|
"PrometheusMiddleware",
|
|
474
500
|
"RSAWebhookSignatureVerifier",
|
|
475
501
|
"RabbitMQSettings",
|
|
476
502
|
"RateLimitMiddleware",
|
|
477
503
|
"RateLimitResult",
|
|
478
504
|
"RateLimitStore",
|
|
505
|
+
"RatioField",
|
|
479
506
|
"RedisFeatureFlagBackend",
|
|
480
507
|
"RedisIdempotencyStore",
|
|
481
508
|
"RedisRateLimitStore",
|
|
@@ -499,6 +526,7 @@ __all__: list[str] = [
|
|
|
499
526
|
"SignupResponseSchema",
|
|
500
527
|
"SignupSchema",
|
|
501
528
|
"SlowQueryLogger",
|
|
529
|
+
"SlugField",
|
|
502
530
|
"SoftDeleteMixin",
|
|
503
531
|
"StateBR",
|
|
504
532
|
"StoredFileServiceMixin",
|
{tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/controllers/base.py
RENAMED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
from typing import Any, Generic, TypeVar, cast
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
|
+
from tempest_fastapi_sdk.schemas.base import BaseSchema
|
|
8
9
|
from tempest_fastapi_sdk.services.base import BaseService
|
|
9
10
|
|
|
10
11
|
ServiceT = TypeVar("ServiceT", bound=BaseService[Any, Any])
|
|
@@ -112,6 +113,18 @@ class BaseController(Generic[ServiceT, ResponseT]):
|
|
|
112
113
|
"""
|
|
113
114
|
return await self.service.count(filters)
|
|
114
115
|
|
|
116
|
+
async def update(self, id: UUID, data: BaseSchema) -> ResponseT:
|
|
117
|
+
"""Pass-through to :meth:`BaseService.update`.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
id (UUID): The primary key of the record to update.
|
|
121
|
+
data (BaseSchema): The update payload (unset fields skipped).
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
ResponseT: The mapped, updated response.
|
|
125
|
+
"""
|
|
126
|
+
return cast("ResponseT", await self.service.update(id, data))
|
|
127
|
+
|
|
115
128
|
async def delete(self, id: UUID) -> None:
|
|
116
129
|
"""Pass-through to :meth:`BaseService.delete`.
|
|
117
130
|
|
{tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/services/base.py
RENAMED
|
@@ -7,6 +7,7 @@ from typing import Any, Generic, TypeVar
|
|
|
7
7
|
from uuid import UUID
|
|
8
8
|
|
|
9
9
|
from tempest_fastapi_sdk.db.repository import BaseRepository
|
|
10
|
+
from tempest_fastapi_sdk.schemas.base import BaseSchema
|
|
10
11
|
|
|
11
12
|
RepositoryT = TypeVar("RepositoryT", bound=BaseRepository[Any])
|
|
12
13
|
ResponseT = TypeVar("ResponseT")
|
|
@@ -168,6 +169,39 @@ class BaseService(Generic[RepositoryT, ResponseT]):
|
|
|
168
169
|
"""
|
|
169
170
|
return await self.repository.exists(filters)
|
|
170
171
|
|
|
172
|
+
async def update(self, id: UUID, data: BaseSchema) -> ResponseT:
|
|
173
|
+
"""Apply a partial update to a record and map it to a response.
|
|
174
|
+
|
|
175
|
+
Fetches the row by primary key, copies the fields present in
|
|
176
|
+
``data`` onto the instance, persists, and returns the mapped
|
|
177
|
+
response. Because :meth:`BaseSchema.to_dict` drops unset and
|
|
178
|
+
``None`` fields, only the values the caller actually supplied are
|
|
179
|
+
applied — so the same method serves both full (PUT) and partial
|
|
180
|
+
(PATCH) updates.
|
|
181
|
+
|
|
182
|
+
Override this in a concrete service when an update needs
|
|
183
|
+
orchestration (cross-repository writes, domain rules, side
|
|
184
|
+
effects); leave it untouched for plain field copies.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
id (UUID): The primary key of the record to update.
|
|
188
|
+
data (BaseSchema): The update payload. Fields left unset (or
|
|
189
|
+
``None``) are not applied.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
ResponseT: The mapped, updated response.
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
AppException: ``repository.not_found_exception`` when no
|
|
196
|
+
record with ``id`` exists.
|
|
197
|
+
ConflictException: On integrity violations while persisting.
|
|
198
|
+
"""
|
|
199
|
+
instance = await self.repository.get_by_id(id)
|
|
200
|
+
for field, value in data.to_dict().items():
|
|
201
|
+
setattr(instance, field, value)
|
|
202
|
+
updated = await self.repository.update(instance)
|
|
203
|
+
return await self._map_to_response(updated)
|
|
204
|
+
|
|
171
205
|
async def delete(self, id: UUID) -> None:
|
|
172
206
|
"""Delete a row by primary key.
|
|
173
207
|
|
{tempest_fastapi_sdk-0.76.0 → tempest_fastapi_sdk-0.78.0}/tempest_fastapi_sdk/utils/__init__.py
RENAMED
|
@@ -21,6 +21,22 @@ from tempest_fastapi_sdk.utils.download import (
|
|
|
21
21
|
build_content_disposition,
|
|
22
22
|
)
|
|
23
23
|
from tempest_fastapi_sdk.utils.email import EmailUtils
|
|
24
|
+
from tempest_fastapi_sdk.utils.fields import (
|
|
25
|
+
CentsField,
|
|
26
|
+
HexColorField,
|
|
27
|
+
LatitudeField,
|
|
28
|
+
LongitudeField,
|
|
29
|
+
NonEmptyStrField,
|
|
30
|
+
NonNegativeFloatField,
|
|
31
|
+
NonNegativeIntField,
|
|
32
|
+
PercentField,
|
|
33
|
+
PortField,
|
|
34
|
+
PositiveFloatField,
|
|
35
|
+
PositiveIntField,
|
|
36
|
+
PriceField,
|
|
37
|
+
RatioField,
|
|
38
|
+
SlugField,
|
|
39
|
+
)
|
|
24
40
|
from tempest_fastapi_sdk.utils.http_client import (
|
|
25
41
|
REQUEST_ID_HEADER,
|
|
26
42
|
CircuitOpenError,
|
|
@@ -123,6 +139,7 @@ __all__: list[str] = [
|
|
|
123
139
|
"CPFOrCNPJ",
|
|
124
140
|
"CPFOrCNPJField",
|
|
125
141
|
"CPUMetrics",
|
|
142
|
+
"CentsField",
|
|
126
143
|
"ChoiceBR",
|
|
127
144
|
"CircuitOpenError",
|
|
128
145
|
"CityBR",
|
|
@@ -132,17 +149,30 @@ __all__: list[str] = [
|
|
|
132
149
|
"EmailUtils",
|
|
133
150
|
"GPUMetrics",
|
|
134
151
|
"HTTPClient",
|
|
152
|
+
"HexColorField",
|
|
135
153
|
"JWTUtils",
|
|
154
|
+
"LatitudeField",
|
|
136
155
|
"LocalUploadStorage",
|
|
137
156
|
"LogUtils",
|
|
157
|
+
"LongitudeField",
|
|
138
158
|
"MemoryMetrics",
|
|
139
159
|
"MetricsUtils",
|
|
140
160
|
"MinIOUploadStorage",
|
|
161
|
+
"NonEmptyStrField",
|
|
162
|
+
"NonNegativeFloatField",
|
|
163
|
+
"NonNegativeIntField",
|
|
141
164
|
"PasswordUtils",
|
|
165
|
+
"PercentField",
|
|
142
166
|
"PhoneBR",
|
|
143
167
|
"PhoneBRField",
|
|
168
|
+
"PortField",
|
|
169
|
+
"PositiveFloatField",
|
|
170
|
+
"PositiveIntField",
|
|
171
|
+
"PriceField",
|
|
172
|
+
"RatioField",
|
|
144
173
|
"Region",
|
|
145
174
|
"RetryPolicy",
|
|
175
|
+
"SlugField",
|
|
146
176
|
"StateBR",
|
|
147
177
|
"SystemMetrics",
|
|
148
178
|
"TOTPHelper",
|