tempest-fastapi-sdk 0.166.1__tar.gz → 0.167.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.166.1 → tempest_fastapi_sdk-0.167.0}/CHANGELOG.md +54 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/CLAUDE.md +19 -1
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/PKG-INFO +36 -3
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/README.md +35 -2
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/authz.en.md +7 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/authz.md +7 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/cli.en.md +31 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/cli.md +30 -0
- tempest_fastapi_sdk-0.167.0/docs/recipes/permission-guards.en.md +320 -0
- tempest_fastapi_sdk-0.167.0/docs/recipes/permission-guards.md +319 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/reference.md +6 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/roadmap.en.md +12 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/roadmap.md +12 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/mkdocs.yml +2 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/pyproject.toml +1 -1
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/__init__.py +13 -1
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/authz/__init__.py +18 -0
- tempest_fastapi_sdk-0.167.0/tempest_fastapi_sdk/authz/requires.py +739 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/main.py +91 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/openapi_errors.py +12 -0
- tempest_fastapi_sdk-0.167.0/tempest_fastapi_sdk/cli/permissions.py +724 -0
- tempest_fastapi_sdk-0.167.0/tests/authz/test_requires.py +554 -0
- tempest_fastapi_sdk-0.167.0/tests/cli/test_permissions.py +389 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/uv.lock +1 -1
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.github/workflows/ci.yml +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.github/workflows/docs.yml +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.github/workflows/nightly-model.yml +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.gitignore +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/.python-version +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/Makefile +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/admin-showcase.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/admin-showcase.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/architecture.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/architecture.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/changelog.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/changelog.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/contributing.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/contributing.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/fullstack-web.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/fullstack-web.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/genai-examples.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/genai-examples.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/index.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/index.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/installation.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/installation.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/integrated.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/integrated.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/index.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/index.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/api.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/api.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/business-rules.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/business-rules.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/domain.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/domain.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/flows.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/flows.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/index.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/learning/marketplace/index.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/marketplace-local.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/marketplace-local.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/migration.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/migration.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/admin.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/admin.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/artifact-registry.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/artifact-registry.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/audit-trail.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/audit-trail.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/auth-flow.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/auth-flow.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/br-helpers.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/br-helpers.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/cache.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/cache.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/chat.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/chat.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/database.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/database.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/deploy-safety.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/deploy-safety.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/downloads.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/downloads.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/email.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/email.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/feature-flags.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/feature-flags.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/fields.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/fields.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/file-store.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/file-store.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/genai.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/genai.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/geo.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/geo.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/http-client.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/http-client.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/http.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/http.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/idempotency.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/idempotency.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/index.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/index.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/introspection-auth.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/introspection-auth.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/logging.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/logging.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/management-commands.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/management-commands.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/metrics.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/metrics.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/mfa.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/mfa.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/multi-tenant.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/multi-tenant.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/observability.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/observability.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/offline-sync.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/offline-sync.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/openapi-client.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/openapi-client.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/openapi-errors.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/openapi-errors.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/outbox.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/outbox.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/queue-tasks.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/queue-tasks.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/react-spa.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/react-spa.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/realtime.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/realtime.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/refresh-tokens.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/refresh-tokens.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/reviews.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/reviews.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/security.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/security.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/sessions.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/sessions.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/sse.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/sse.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/storage.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/storage.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/stored-files.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/stored-files.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/system-checks.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/system-checks.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/tempestweb-frontend.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/tempestweb-frontend.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/testing.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/testing.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/typing.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/typing.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/uploads.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/uploads.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/utilities.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/utilities.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/vision.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/vision.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/webpush.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/webpush.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/websocket.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/recipes/websocket.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/reference.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/ssr.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/ssr.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/tour.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/tour.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/tutorial.en.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/docs/tutorial.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/mkdocs_hooks/llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/README.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/manual-validation.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/phase-0.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/phase-1.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/phase-2.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/phase-3.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/planning/genai/validation-strategy.md +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/scripts/extract_recipe.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/actions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/auth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/config.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/dashboard.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/discovery.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/forms.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/permissions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/session.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/site.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/static/admin.css +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/autocomplete.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/detail.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/form.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/import.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/list.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/logs.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/templates/mfa.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/admin/theme.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/dependencies/auth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/error_docs.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/graceful.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/middlewares/response_cache.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/server.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/spa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/static.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/tracing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/artifacts/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/artifacts/actions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/artifacts/digest.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/artifacts/model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/artifacts/registry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/guards.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/introspection.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/locale.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/activation.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_change.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_change_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_change_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_changed_notice.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_verification.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_verification_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/email_verification_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_change.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_change_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_change_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_changed_notice.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/email_verification_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/auth/token_delivery.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/authz/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/authz/permissions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cache/invalidation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/chat/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/chat/models.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/chat/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/chat/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/chat/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/checks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/checks/builtins.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/checks/messages.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/checks/registry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/Dockerfile.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/dockerignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/resources.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/commands.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/config.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/db.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/new.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/openapi_fix.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/secrets.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/src_layers.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/cli/user.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/controllers/base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/core/context.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/core/enums.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/core/logging.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/core/typed.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/audit.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/backup.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/connection.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/expressions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/mixins.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/outbox.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/repository.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/signals.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/slow_query.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/tenant.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/user_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/user_recovery_code_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/user_refresh_token_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/user_token_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/db/webpush_subscription_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/i18n.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/flags/backends.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/flags/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/flags/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/audio/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/audio/language.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/audio/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/audio/stt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/audio/tts.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/batching.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/embeddings.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/generation_cache.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/hardware.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/moderation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/ollama.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/onnx_embed.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/pipeline.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/chroma.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/chunking.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/context.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/extract.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/fusion.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/hybrid.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/pdf.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/rerank.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/retriever.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/search.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/rag/vectorstore.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/registry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/structured.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/text.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/tokens.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/tracing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/genai/vision_text.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/br.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/db.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/distance.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/enums.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/estimate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/geocoding.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/geometry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/polyline.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/routing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/geo/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/emit_client.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/emit_schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/generate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/ir.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/loader.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/naming.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/openapi/parse.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/py.typed +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/queue/broker.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/queue/consumer.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/reviews/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/reviews/models.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/reviews/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/reviews/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/reviews/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/errors.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/services/base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/services/file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/settings/base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/settings/mixins.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sse/broker.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/sse/event_stream.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/_static/htmx.min.js +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/assets.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/attributes.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/page.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/response.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/ssr/webapp.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/storage/minio_client.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/cron.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/dead_letter.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/observability.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/oop.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/queue.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/testing/database.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/testing/factories.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/data/br_locations.json +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/download.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/email.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/fields.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/file_store.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/locations.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/log.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/password.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/totp.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/utils/upload.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/vision/mapping.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/vision/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/vision/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/webpush/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/webpush/service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_actions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_audit_viewer.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_auth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_autocomplete_fk.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_csv_import.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_dashboard_cards.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_discovery.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_forms.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_inlines.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_lenses.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_logs_nav.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_rbac.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_rich_filters.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_site.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_theme.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_upload_field.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_user_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/admin/test_widgets_json_time.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_body_size.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_business_metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_cookies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_cors.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_csrf.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_dependencies_auth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_error_docs.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_graceful.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_handlers.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_health_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_idempotency.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_jwt_dependency.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_logs_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_oauth.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_outbound_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_prometheus.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_rate_limit_extras.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_request_id_middleware.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_response_cache.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_role_dependency.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_server.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_spa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_static.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/api/test_webhooks_rsa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/artifacts/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/artifacts/support.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/artifacts/test_actions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/artifacts/test_digest.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/artifacts/test_registry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_cookie_delivery.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_email_change.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_guards.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_introspection.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_locale.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_refresh.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_refresh_db.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/auth/test_service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/authz/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/authz/test_dependencies.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/authz/test_permissions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cache/test_decorator.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cache/test_invalidation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cache/test_redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/chat/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/chat/test_chat.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/checks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/checks/test_check_config_cli.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/checks/test_checks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_config.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_db.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_db_seed.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_dockerfile_spa.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_lint_strictness.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_main.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_management_commands.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_openapi_errors.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_openapi_fix.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_secrets.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/cli/test_user.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/conftest.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/controllers/test_base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/core/test_context.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/core/test_enums.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/core/test_logging.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/core/test_typed.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_audit.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_backup.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_bulk_ops.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_connection.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_eager_load.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_expressions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_migrations.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_model.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_outbox.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_repository.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_safe_upgrade.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_signals.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_slow_query.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/db/test_tenant.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/exceptions/test_exceptions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/exceptions/test_i18n.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/exceptions/test_inherited_code_warning.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/flags/test_flags.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/_eval/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/_eval/corpus.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/audio/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/audio/test_audio.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/audio/test_language.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/conftest.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_batching.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_chat_memory.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_embedding_cache_redis.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_embeddings.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_eval_harness.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_genai_metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_generation_cache.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_generation_config.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_gpu_validation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_hardware.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_hybrid.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_moderation.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_ollama.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_onnx_embed.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_pipeline.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_pipeline_integration.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_rag.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_refinements.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_rerank.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_structured.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_text.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_textgen_embed_metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_tokens.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_vectorstore.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/genai/test_vision_text.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_br.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_db.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_distance.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_estimate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_geocoding.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_geometry.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_polyline.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_routing.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/geo/test_routing_extra.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/conftest.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/test_loader.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/test_naming.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/openapi/test_parse.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/queue/test_broker.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/queue/test_consumer.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/queue/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/reviews/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/reviews/test_reviews.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_cursor_pagination.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_errors.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_link_headers.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_pagination.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/schemas/test_response.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/services/test_base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/services/test_file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/sessions/test_sessions.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/settings/test_base.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/settings/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/sse/test_broker.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/sse/test_event_stream.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/test_attributes.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/test_integration.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/test_page.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/test_response.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/ssr/test_webapp.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/storage/test_minio_client.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_cron.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_dead_letter.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_observability.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_oop.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_queue.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/tasks/test_scheduler.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/test_docs_api_guard.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/test_llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/test_reference_coverage.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/testing/test_database.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/testing/test_factories.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_client_ip.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_datetime.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_dict.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_download.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_email.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_fields.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_file_store.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_http_client.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_jwt.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_lazy_extras.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_locations.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_log.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_metrics.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_password.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_regex.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_throttle.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/utils/test_upload.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/vision/test_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/vision/test_vision.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/webpush/test_dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/webpush/test_router.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/webpush/test_schemas.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/webpush/test_service.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.166.1 → tempest_fastapi_sdk-0.167.0}/tests/websockets/test_hub_and_router.py +0 -0
|
@@ -5,6 +5,60 @@ 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.167.0] — 2026-07-26
|
|
9
|
+
|
|
10
|
+
Permission guards: a decorator that runs plain `(user) -> user | None`
|
|
11
|
+
functions before a function body, plus the two-layer misuse check the user
|
|
12
|
+
asked for — fail-fast at import time, static gate in CI.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`@requires(*guards, user_param=None)`** (`tempest_fastapi_sdk.authz`,
|
|
17
|
+
re-exported at the package root). Runs each guard on the user before the
|
|
18
|
+
decorated body, left to right, on a route handler, a controller or a service
|
|
19
|
+
method, sync or `async`. A guard receives the user, denies by raising an
|
|
20
|
+
`AppException` subclass (so the status, the error `code` and the
|
|
21
|
+
`{detail, code, details}` envelope come from `register_exception_handlers`),
|
|
22
|
+
and returns the user or `None`; a non-`None` return replaces the user the next
|
|
23
|
+
guard and the body see, which is how `require_authenticated` /
|
|
24
|
+
`require_active` / `require_admin` narrow `UserT | None` to `UserT`.
|
|
25
|
+
The user parameter is resolved from the annotations — the single parameter
|
|
26
|
+
typed as a `BaseModel` / `BaseUserModel` subclass — with `user_param=` to
|
|
27
|
+
name it explicitly or disambiguate two user models. The wrapper keeps the
|
|
28
|
+
decorated signature (with annotations already evaluated, so FastAPI resolves
|
|
29
|
+
them against the right module), leaving dependency injection and the OpenAPI
|
|
30
|
+
schema untouched.
|
|
31
|
+
- **`TempestPermissionError`** — raised at decoration time (import time) for
|
|
32
|
+
`@requires()` with no guard, a non-callable guard, a guard that does not take
|
|
33
|
+
exactly one fillable parameter, an `async` guard under a synchronous function,
|
|
34
|
+
or a decorated function whose user parameter cannot be resolved. The
|
|
35
|
+
application refuses to start instead of running a check that never fires.
|
|
36
|
+
- **`GuardContractWarning`** — warned at call time when a guard raises outside
|
|
37
|
+
the `AppException` hierarchy (the API layer would answer HTTP 500 with no
|
|
38
|
+
error code) or returns a non-user value such as `False` (a predicate-style
|
|
39
|
+
check whose denial cannot be honored). The original exception still
|
|
40
|
+
propagates; the warning names the guard.
|
|
41
|
+
- **`declared_guards(fn)` / `guarded_user_param(fn)`** — read a function's
|
|
42
|
+
guards and its user parameter without calling it, for a router audit or a
|
|
43
|
+
test asserting every write route carries a guard.
|
|
44
|
+
- **`tempest permissions [--check] [--strict] [--path]`** — static contract
|
|
45
|
+
check over the project source (`ast`, without importing the application), for
|
|
46
|
+
what runtime validation cannot see: a guard whose `raise` no test exercises, a
|
|
47
|
+
guard never wired. Errors: `no-guards`, `user-param-missing`,
|
|
48
|
+
`user-param-ambiguous`, `guard-arity`, `guard-async-in-sync`,
|
|
49
|
+
`guard-returns-bool`, `guard-foreign-exception`. Warnings:
|
|
50
|
+
`guard-never-denies`, `guard-missing-annotation`, `guard-return-type`,
|
|
51
|
+
`guard-unresolved`. `--check` exits non-zero on errors, `--strict` on warnings
|
|
52
|
+
too. Guards resolve by name; an ambiguous or out-of-scope name is reported as
|
|
53
|
+
`guard-unresolved` rather than checked against the wrong definition.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **`tempest openapi-errors` now follows `@requires` guards.** A guard denies by
|
|
58
|
+
raising, so its exceptions are as reachable from the route as those of any
|
|
59
|
+
function the body calls; they now show up as `undocumented` until the route
|
|
60
|
+
declares them, and `--fix` writes them like any other.
|
|
61
|
+
|
|
8
62
|
## [0.166.1] — 2026-07-25
|
|
9
63
|
|
|
10
64
|
Post-release validation of `--fix` against the published wheel, in a project
|
|
@@ -75,6 +75,24 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
75
75
|
`refresh_token_model=` on `UserAuthService`) with rotation,
|
|
76
76
|
family-wide reuse detection and `POST /auth/logout`
|
|
77
77
|
(`LogoutSchema`).
|
|
78
|
+
- **Permission guards (v0.167.0)** — `@requires(*guards, user_param=None)`
|
|
79
|
+
(`tempest_fastapi_sdk.authz`, re-exported at the root) runs plain
|
|
80
|
+
`(user) -> user | None` guards before a function body, at any layer, sync or
|
|
81
|
+
async; guards deny by raising an `AppException`, and a non-`None` return
|
|
82
|
+
replaces the user the body sees (how `require_active` narrows `UserT | None`).
|
|
83
|
+
The user param resolves from the annotations (`BaseModel`/`BaseUserModel`
|
|
84
|
+
subclass), `user_param=` disambiguates. Misuse caught in three places:
|
|
85
|
+
`TempestPermissionError` at import (no guard, wrong arity, async guard on a
|
|
86
|
+
sync fn, unresolvable user param), `GuardContractWarning` at call time
|
|
87
|
+
(foreign exception, `return False`), and
|
|
88
|
+
`tempest permissions [--check|--strict|--path]` statically (`ast`) — errors
|
|
89
|
+
`no-guards`/`user-param-missing`/`user-param-ambiguous`/`guard-arity`/
|
|
90
|
+
`guard-async-in-sync`/`guard-returns-bool`/`guard-foreign-exception`,
|
|
91
|
+
warnings `guard-never-denies`/`guard-missing-annotation`/`guard-return-type`/
|
|
92
|
+
`guard-unresolved` (ambiguous or out-of-scope guard reported, never guessed).
|
|
93
|
+
`openapi-errors` follows the guards, so their exceptions land in
|
|
94
|
+
`error_responses(...)`. `declared_guards`/`guarded_user_param` introspect a
|
|
95
|
+
route. Recipe: `docs/recipes/permission-guards.md`.
|
|
78
96
|
- **DB** — `AsyncDatabaseManager`, `BaseRepository[T]` with
|
|
79
97
|
bulk ops (`bulk_create_values`, `bulk_upsert`, `bulk_update`,
|
|
80
98
|
`add_all`, etc.), `AlembicHelper`, `BaseModel`, audit /
|
|
@@ -377,7 +395,7 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
377
395
|
`tempest db init/revision/upgrade/downgrade/current/history/seed`,
|
|
378
396
|
`tempest user create [--admin] / list`, `tempest secrets rotate`,
|
|
379
397
|
plus quality gates (`lint`, `fix`, `format`, `fmt-check`, `type`,
|
|
380
|
-
`test`, `check`), `openapi-errors`, `openapi-client`.
|
|
398
|
+
`test`, `check`), `openapi-errors`, `openapi-client`, `permissions`.
|
|
381
399
|
|
|
382
400
|
The whole Tier S / Tier A / Tier B backlog that used to live here is
|
|
383
401
|
**shipped**, and so is the five-item next-version plan that followed it
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempest-fastapi-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.167.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
|
|
@@ -237,7 +237,7 @@ Via `pyproject.toml`:
|
|
|
237
237
|
|
|
238
238
|
```toml
|
|
239
239
|
dependencies = [
|
|
240
|
-
"tempest-fastapi-sdk>=0.
|
|
240
|
+
"tempest-fastapi-sdk>=0.167.0",
|
|
241
241
|
]
|
|
242
242
|
```
|
|
243
243
|
|
|
@@ -302,7 +302,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
302
302
|
| `tempest_fastapi_sdk.settings` | `BaseAppSettings` (+ `AppSettingsMeta`), `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
|
|
303
303
|
| `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, OpenAPI error docs (`error_responses`, `raises`, `TempestAPIRouter`, `RaisesSpec`, `declared_raises`), `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `BusinessMetrics`, `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`, outbound `WebhookSender` (+ `WebhookDelivery`), OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `make_spa_router` (serve a compiled React/Vite SPA with a client-side fallback), `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck`, `setup_tracing` *(extra: `[otel]`)* |
|
|
304
304
|
| `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 |
|
|
305
|
-
| `tempest_fastapi_sdk.authz` | Object-level permissions: `permission` (rule decorator), `has_perm` / `check_permission`, `PermissionRegistry` (injectable superuser bypass + static-permission fallback, `order.*`/`*` wildcards), `make_permission_checker` (FastAPI route guard), `PermissionMixin` (`await user.has_perm(perm, obj=...)`), `default_registry` |
|
|
305
|
+
| `tempest_fastapi_sdk.authz` | Object-level permissions: `permission` (rule decorator), `has_perm` / `check_permission`, `PermissionRegistry` (injectable superuser bypass + static-permission fallback, `order.*`/`*` wildcards), `make_permission_checker` (FastAPI route guard), `PermissionMixin` (`await user.has_perm(perm, obj=...)`), `default_registry`, `requires` (guard decorator `(user) -> user | None`, checked at import time + by `tempest permissions`), `declared_guards` / `guarded_user_param`, `TempestPermissionError`, `GuardContractWarning` |
|
|
306
306
|
| `tempest_fastapi_sdk.checks` | System checks (Django-style config validation): `check` (register decorator), `run_checks` / `run_system_checks` (raises `SystemCheckError` on ERROR+), `CheckMessage` / `CheckLevel` + `debug`/`info`/`warning`/`error`/`critical`, `CheckRegistry` / `default_registry`; built-in settings checks + the `tempest check-config` CLI (auto-detects settings, `--tag` / `--fail-level`) |
|
|
307
307
|
| `tempest_fastapi_sdk.controllers` | `BaseController` |
|
|
308
308
|
| `tempest_fastapi_sdk.services` | `BaseService` |
|
|
@@ -4147,6 +4147,39 @@ tempest openapi-errors --fix # write them (needs a clean git tree)
|
|
|
4147
4147
|
|
|
4148
4148
|
---
|
|
4149
4149
|
|
|
4150
|
+
### Permission guards
|
|
4151
|
+
|
|
4152
|
+
`@requires` runs plain `(user) -> user | None` guards before a function body — on a route, a controller or a service, sync or `async`. A guard denies by raising an `AppException`, so the HTTP status, the error `code` and the `{detail, code, details}` envelope come from the SDK handlers.
|
|
4153
|
+
|
|
4154
|
+
```python
|
|
4155
|
+
from fastapi import Depends
|
|
4156
|
+
from tempest_fastapi_sdk import error_responses, requires
|
|
4157
|
+
from tempest_fastapi_sdk.auth import require_active
|
|
4158
|
+
|
|
4159
|
+
|
|
4160
|
+
@router.delete("/orders/{order_id}", responses=error_responses(NotOrderOwnerException))
|
|
4161
|
+
@requires(require_active, order_owner)
|
|
4162
|
+
async def delete_order(
|
|
4163
|
+
order_id: UUID,
|
|
4164
|
+
user: UserModel = Depends(get_current_user),
|
|
4165
|
+
) -> None:
|
|
4166
|
+
"""The body runs only for an active user who owns the order."""
|
|
4167
|
+
await controller.delete(order_id)
|
|
4168
|
+
```
|
|
4169
|
+
|
|
4170
|
+
The user parameter is found by annotation (`user_param=` breaks a tie), and a guard's non-`None` return replaces the user the body sees — which is how `require_active` narrows `UserT | None` to `UserT`.
|
|
4171
|
+
|
|
4172
|
+
Misuse is caught in three places: `TempestPermissionError` at import time (no guard, wrong arity, `async` guard on a sync function, no user parameter), `GuardContractWarning` at call time (a guard raising outside the `AppException` hierarchy, or returning `False` instead of denying), and `tempest permissions --check` in CI, which reads the same contract statically.
|
|
4173
|
+
|
|
4174
|
+
```bash
|
|
4175
|
+
tempest permissions --check # exit 1 on any error
|
|
4176
|
+
tempest permissions --check --strict # fail on warnings too
|
|
4177
|
+
```
|
|
4178
|
+
|
|
4179
|
+
`tempest openapi-errors` reads the `@requires` guards too, so a guard's exception shows up as `undocumented` on the route until it is declared. Full walkthrough: [Permission guards](https://mauriciobenjamin700.github.io/tempest-fastapi-sdk/en/recipes/permission-guards/).
|
|
4180
|
+
|
|
4181
|
+
---
|
|
4182
|
+
|
|
4150
4183
|
## Conventions
|
|
4151
4184
|
|
|
4152
4185
|
- **Layered architecture**: routers → controllers → services → repositories. Never skip layers.
|
|
@@ -91,7 +91,7 @@ Via `pyproject.toml`:
|
|
|
91
91
|
|
|
92
92
|
```toml
|
|
93
93
|
dependencies = [
|
|
94
|
-
"tempest-fastapi-sdk>=0.
|
|
94
|
+
"tempest-fastapi-sdk>=0.167.0",
|
|
95
95
|
]
|
|
96
96
|
```
|
|
97
97
|
|
|
@@ -156,7 +156,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
156
156
|
| `tempest_fastapi_sdk.settings` | `BaseAppSettings` (+ `AppSettingsMeta`), `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
|
|
157
157
|
| `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, OpenAPI error docs (`error_responses`, `raises`, `TempestAPIRouter`, `RaisesSpec`, `declared_raises`), `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `BusinessMetrics`, `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`, outbound `WebhookSender` (+ `WebhookDelivery`), OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `make_spa_router` (serve a compiled React/Vite SPA with a client-side fallback), `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck`, `setup_tracing` *(extra: `[otel]`)* |
|
|
158
158
|
| `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 |
|
|
159
|
-
| `tempest_fastapi_sdk.authz` | Object-level permissions: `permission` (rule decorator), `has_perm` / `check_permission`, `PermissionRegistry` (injectable superuser bypass + static-permission fallback, `order.*`/`*` wildcards), `make_permission_checker` (FastAPI route guard), `PermissionMixin` (`await user.has_perm(perm, obj=...)`), `default_registry` |
|
|
159
|
+
| `tempest_fastapi_sdk.authz` | Object-level permissions: `permission` (rule decorator), `has_perm` / `check_permission`, `PermissionRegistry` (injectable superuser bypass + static-permission fallback, `order.*`/`*` wildcards), `make_permission_checker` (FastAPI route guard), `PermissionMixin` (`await user.has_perm(perm, obj=...)`), `default_registry`, `requires` (guard decorator `(user) -> user | None`, checked at import time + by `tempest permissions`), `declared_guards` / `guarded_user_param`, `TempestPermissionError`, `GuardContractWarning` |
|
|
160
160
|
| `tempest_fastapi_sdk.checks` | System checks (Django-style config validation): `check` (register decorator), `run_checks` / `run_system_checks` (raises `SystemCheckError` on ERROR+), `CheckMessage` / `CheckLevel` + `debug`/`info`/`warning`/`error`/`critical`, `CheckRegistry` / `default_registry`; built-in settings checks + the `tempest check-config` CLI (auto-detects settings, `--tag` / `--fail-level`) |
|
|
161
161
|
| `tempest_fastapi_sdk.controllers` | `BaseController` |
|
|
162
162
|
| `tempest_fastapi_sdk.services` | `BaseService` |
|
|
@@ -4001,6 +4001,39 @@ tempest openapi-errors --fix # write them (needs a clean git tree)
|
|
|
4001
4001
|
|
|
4002
4002
|
---
|
|
4003
4003
|
|
|
4004
|
+
### Permission guards
|
|
4005
|
+
|
|
4006
|
+
`@requires` runs plain `(user) -> user | None` guards before a function body — on a route, a controller or a service, sync or `async`. A guard denies by raising an `AppException`, so the HTTP status, the error `code` and the `{detail, code, details}` envelope come from the SDK handlers.
|
|
4007
|
+
|
|
4008
|
+
```python
|
|
4009
|
+
from fastapi import Depends
|
|
4010
|
+
from tempest_fastapi_sdk import error_responses, requires
|
|
4011
|
+
from tempest_fastapi_sdk.auth import require_active
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
@router.delete("/orders/{order_id}", responses=error_responses(NotOrderOwnerException))
|
|
4015
|
+
@requires(require_active, order_owner)
|
|
4016
|
+
async def delete_order(
|
|
4017
|
+
order_id: UUID,
|
|
4018
|
+
user: UserModel = Depends(get_current_user),
|
|
4019
|
+
) -> None:
|
|
4020
|
+
"""The body runs only for an active user who owns the order."""
|
|
4021
|
+
await controller.delete(order_id)
|
|
4022
|
+
```
|
|
4023
|
+
|
|
4024
|
+
The user parameter is found by annotation (`user_param=` breaks a tie), and a guard's non-`None` return replaces the user the body sees — which is how `require_active` narrows `UserT | None` to `UserT`.
|
|
4025
|
+
|
|
4026
|
+
Misuse is caught in three places: `TempestPermissionError` at import time (no guard, wrong arity, `async` guard on a sync function, no user parameter), `GuardContractWarning` at call time (a guard raising outside the `AppException` hierarchy, or returning `False` instead of denying), and `tempest permissions --check` in CI, which reads the same contract statically.
|
|
4027
|
+
|
|
4028
|
+
```bash
|
|
4029
|
+
tempest permissions --check # exit 1 on any error
|
|
4030
|
+
tempest permissions --check --strict # fail on warnings too
|
|
4031
|
+
```
|
|
4032
|
+
|
|
4033
|
+
`tempest openapi-errors` reads the `@requires` guards too, so a guard's exception shows up as `undocumented` on the route until it is declared. Full walkthrough: [Permission guards](https://mauriciobenjamin700.github.io/tempest-fastapi-sdk/en/recipes/permission-guards/).
|
|
4034
|
+
|
|
4035
|
+
---
|
|
4036
|
+
|
|
4004
4037
|
## Conventions
|
|
4005
4038
|
|
|
4006
4039
|
- **Layered architecture**: routers → controllers → services → repositories. Never skip layers.
|
|
@@ -183,3 +183,10 @@ The mixin delegates to the global registry (`default_registry`).
|
|
|
183
183
|
- Superuser and static set are injectable via `PermissionRegistry`.
|
|
184
184
|
- Rules match by exact string or wildcard (`order.*`, `*`).
|
|
185
185
|
- `PermissionMixin` gives you `await user.has_perm(...)`.
|
|
186
|
+
|
|
187
|
+
!!! tip "Already holding the user?"
|
|
188
|
+
When the check is an invariant on the user itself (active, admin, owner of
|
|
189
|
+
the resource) rather than a question for the registry,
|
|
190
|
+
[`@requires`](permission-guards.md) runs `(user) -> user | None` guards at
|
|
191
|
+
any layer — and a guard may call `check_permission(...)` to combine both
|
|
192
|
+
approaches.
|
|
@@ -182,3 +182,10 @@ O mixin delega ao registry global (`default_registry`).
|
|
|
182
182
|
- Superusuário e conjunto estático são injetáveis via `PermissionRegistry`.
|
|
183
183
|
- Regras batem por string exata ou wildcard (`order.*`, `*`).
|
|
184
184
|
- `PermissionMixin` dá o `await user.has_perm(...)`.
|
|
185
|
+
|
|
186
|
+
!!! tip "Já tem o usuário na mão?"
|
|
187
|
+
Quando a checagem é uma invariante sobre o próprio usuário (ativo, admin,
|
|
188
|
+
dono do recurso) e não uma pergunta ao registry, o
|
|
189
|
+
[`@requires`](permission-guards.md) roda guards `(user) -> user | None` em
|
|
190
|
+
qualquer camada — e um guard pode chamar `check_permission(...)` para
|
|
191
|
+
combinar as duas abordagens.
|
|
@@ -504,6 +504,37 @@ Details and limitations in the [Errors in OpenAPI »](openapi-errors.md) recipe.
|
|
|
504
504
|
|
|
505
505
|
---
|
|
506
506
|
|
|
507
|
+
### Permission guards — `tempest permissions`
|
|
508
|
+
|
|
509
|
+
Reads the `@requires` guard contract straight off the source (`ast`, without
|
|
510
|
+
importing the application) and reports what the decorator cannot see at import
|
|
511
|
+
time:
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
tempest permissions # informative report (exit 0)
|
|
515
|
+
tempest permissions --check # exit 1 on any error (CI gate)
|
|
516
|
+
tempest permissions --check --strict # fail on warnings too
|
|
517
|
+
tempest permissions --path src --path libs
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
```text
|
|
521
|
+
src/api/routers/orders.py:41 delete_order
|
|
522
|
+
error: guard-foreign-exception: guard 'order_owner' raises ValueError, which is
|
|
523
|
+
not an AppException subclass; the API layer answers it as HTTP 500 without an
|
|
524
|
+
error code
|
|
525
|
+
2 finding(s), 1 error(s).
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Errors: a guard raising outside the `AppException` hierarchy, a predicate-style
|
|
529
|
+
guard (`-> bool`), wrong arity, an `async` guard on a sync function, a route with
|
|
530
|
+
no user parameter. Warnings: a guard that never denies, a missing annotation, a
|
|
531
|
+
guard the checker could not resolve (lambda, duplicated name, definition outside
|
|
532
|
+
the scanned paths).
|
|
533
|
+
|
|
534
|
+
Details in the [Permission guards (`@requires`) »](permission-guards.md) recipe.
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
507
538
|
### Integration client — `tempest openapi-client`
|
|
508
539
|
|
|
509
540
|
Generates Pydantic schemas + a typed HTTP client from a third party's OpenAPI
|
|
@@ -502,6 +502,36 @@ Detalhes e limitações na receita [Erros no OpenAPI »](openapi-errors.md).
|
|
|
502
502
|
|
|
503
503
|
---
|
|
504
504
|
|
|
505
|
+
### Guards de permissão — `tempest permissions`
|
|
506
|
+
|
|
507
|
+
Lê o contrato dos guards do `@requires` direto do código-fonte (`ast`, sem
|
|
508
|
+
importar a aplicação) e reporta o que o decorator não consegue ver em tempo de
|
|
509
|
+
import:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
tempest permissions # relatório informativo (exit 0)
|
|
513
|
+
tempest permissions --check # exit 1 se houver erro (gate de CI)
|
|
514
|
+
tempest permissions --check --strict # falha também nos warnings
|
|
515
|
+
tempest permissions --path src --path libs
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
```text
|
|
519
|
+
src/api/routers/orders.py:41 delete_order
|
|
520
|
+
error: guard-foreign-exception: guard 'order_owner' raises ValueError, which is
|
|
521
|
+
not an AppException subclass; the API layer answers it as HTTP 500 without an
|
|
522
|
+
error code
|
|
523
|
+
2 finding(s), 1 error(s).
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
Erros: guard que levanta fora da hierarquia `AppException`, guard-predicado
|
|
527
|
+
(`-> bool`), aridade errada, guard `async` em função sync, rota sem parâmetro de
|
|
528
|
+
usuário. Warnings: guard que nunca nega, anotação faltando, guard que o checker
|
|
529
|
+
não conseguiu resolver (lambda, nome duplicado, definição fora do escopo).
|
|
530
|
+
|
|
531
|
+
Detalhes na receita [Guards de permissão (`@requires`) »](permission-guards.md).
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
505
535
|
### Cliente de integração — `tempest openapi-client`
|
|
506
536
|
|
|
507
537
|
Gera schemas Pydantic + um cliente HTTP tipado a partir da especificação OpenAPI
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Permission guards (`@requires`)
|
|
2
|
+
|
|
3
|
+
You already hold the user — it came from a dependency, or from a service
|
|
4
|
+
parameter — and you want to assert an invariant before the function body runs:
|
|
5
|
+
"must be active", "must own the order", "must be an admin".
|
|
6
|
+
|
|
7
|
+
`@requires` does that with plain functions: no framework, no registry, no magic
|
|
8
|
+
strings. 🚀
|
|
9
|
+
|
|
10
|
+
## The problem
|
|
11
|
+
|
|
12
|
+
Without a decorator, the check becomes noise at the top of every function:
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
async def delete_order(order_id: UUID, user: UserModel | None) -> None:
|
|
16
|
+
if user is None:
|
|
17
|
+
raise UnauthorizedException(message="Authentication required")
|
|
18
|
+
if not user.is_active:
|
|
19
|
+
raise ForbiddenException(message="User account is inactive")
|
|
20
|
+
if order_id not in user.owned_orders:
|
|
21
|
+
raise ForbiddenException(message="Not the order owner")
|
|
22
|
+
...
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Three problems: repetition across every route, authorization mixed into business
|
|
26
|
+
logic, and nothing stops someone from writing `if not allowed: return None`
|
|
27
|
+
instead of raising — the route answers 200 on a denial.
|
|
28
|
+
|
|
29
|
+
## The solution in 2 steps
|
|
30
|
+
|
|
31
|
+
### 1. Write the guard
|
|
32
|
+
|
|
33
|
+
A guard is an ordinary function: it **takes the user**, **returns the user** (or
|
|
34
|
+
`None`) and **denies by raising** an `AppException`.
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from tempest_fastapi_sdk import ForbiddenException
|
|
38
|
+
|
|
39
|
+
from src.db.models import UserModel
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def order_owner(user: UserModel) -> UserModel:
|
|
43
|
+
"""Assert the user owns the order under edit.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
user (UserModel): The authenticated user.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
UserModel: The same user.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
NotOrderOwnerException: When the user does not own the order.
|
|
53
|
+
"""
|
|
54
|
+
if not user.owns_current_order:
|
|
55
|
+
raise NotOrderOwnerException()
|
|
56
|
+
return user
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
!!! warning "A guard denies by raising, never by returning `False`"
|
|
60
|
+
`return False` denies **nothing** — `@requires` ignores the value and warns
|
|
61
|
+
with `GuardContractWarning`, and `tempest permissions` reports
|
|
62
|
+
`guard-returns-bool` as an error. The reason is error standardization:
|
|
63
|
+
raising an `AppException` gets you the HTTP status, the `code` and the
|
|
64
|
+
`{detail, code, details}` envelope for free from the SDK handlers.
|
|
65
|
+
|
|
66
|
+
### 2. Decorate the function
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from uuid import UUID
|
|
70
|
+
|
|
71
|
+
from fastapi import Depends
|
|
72
|
+
from tempest_fastapi_sdk import error_responses, requires
|
|
73
|
+
from tempest_fastapi_sdk.auth import require_active
|
|
74
|
+
|
|
75
|
+
from src.api.dependencies import get_current_user
|
|
76
|
+
from src.api.guards import order_owner
|
|
77
|
+
from src.core.exceptions import NotOrderOwnerException
|
|
78
|
+
from src.db.models import UserModel
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@router.delete(
|
|
82
|
+
"/orders/{order_id}",
|
|
83
|
+
responses=error_responses(NotOrderOwnerException),
|
|
84
|
+
)
|
|
85
|
+
@requires(require_active, order_owner)
|
|
86
|
+
async def delete_order(
|
|
87
|
+
order_id: UUID,
|
|
88
|
+
user: UserModel = Depends(get_current_user),
|
|
89
|
+
) -> None:
|
|
90
|
+
"""Delete an order the caller owns.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
order_id (UUID): The order to delete.
|
|
94
|
+
user (UserModel): The authenticated, active, owning user.
|
|
95
|
+
"""
|
|
96
|
+
await controller.delete(order_id)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
That is it. Guards run left to right before the body; the body runs only if all
|
|
100
|
+
of them pass.
|
|
101
|
+
|
|
102
|
+
!!! tip "Decorator order"
|
|
103
|
+
`@requires` goes **below** the route decorator. The router must register the
|
|
104
|
+
already-guarded function.
|
|
105
|
+
|
|
106
|
+
## Where the user comes from
|
|
107
|
+
|
|
108
|
+
`@requires` finds the user parameter **by annotation**: the one whose type is a
|
|
109
|
+
`BaseModel` / `BaseUserModel` subclass. Nothing to configure in the common case.
|
|
110
|
+
|
|
111
|
+
When the signature holds more than one user, point at the right one:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
@requires(can_ban_users, user_param="target")
|
|
115
|
+
async def ban_user(
|
|
116
|
+
actor: UserModel = Depends(get_current_user),
|
|
117
|
+
target: UserModel = Depends(get_target_user),
|
|
118
|
+
) -> None:
|
|
119
|
+
"""Ban the target user.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
actor (UserModel): The moderator performing the ban.
|
|
123
|
+
target (UserModel): The user being banned.
|
|
124
|
+
"""
|
|
125
|
+
...
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
??? info "Technical details — annotation resolution"
|
|
129
|
+
The order is: an explicit `user_param=`; then the single parameter whose
|
|
130
|
+
annotation resolves to a user model; then — only when no annotation resolved
|
|
131
|
+
to one — the single parameter whose name is in `USER_PARAM_NAMES`
|
|
132
|
+
(`user`, `current_user`, `actor`, `requester`, `principal`) or whose textual
|
|
133
|
+
annotation mentions `User`. That last step exists because
|
|
134
|
+
`from __future__ import annotations` plus a `TYPE_CHECKING` import leaves the
|
|
135
|
+
annotation impossible to evaluate at decoration time.
|
|
136
|
+
|
|
137
|
+
When nothing resolves — or two candidates tie — the import fails with
|
|
138
|
+
`TempestPermissionError`. Better an application that refuses to start than
|
|
139
|
+
one running a check that never fires.
|
|
140
|
+
|
|
141
|
+
## The guard's return narrows the type
|
|
142
|
+
|
|
143
|
+
A guard that returns the user replaces the user seen by the next guard **and by
|
|
144
|
+
the function body**. That is how the SDK guards
|
|
145
|
+
(`require_authenticated` / `require_active` / `require_admin`) turn
|
|
146
|
+
`UserT | None` into `UserT`:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
@requires(require_active)
|
|
150
|
+
async def me(user: UserModel | None = Depends(get_current_user_soft)) -> UserModel:
|
|
151
|
+
"""Return the authenticated user.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
user (UserModel | None): Filled by the soft dependency; guaranteed
|
|
155
|
+
non-None inside the body.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
UserModel: The active user.
|
|
159
|
+
"""
|
|
160
|
+
return user
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Returning `None` is allowed and means "I did not touch the user".
|
|
164
|
+
|
|
165
|
+
## Works at any layer
|
|
166
|
+
|
|
167
|
+
Nothing here depends on FastAPI. The same decorator works on a controller or a
|
|
168
|
+
service, sync or `async`:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from tempest_fastapi_sdk import requires
|
|
172
|
+
|
|
173
|
+
from src.api.guards import order_owner
|
|
174
|
+
from src.db.models import UserModel
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class OrderService:
|
|
178
|
+
"""Business logic for orders."""
|
|
179
|
+
|
|
180
|
+
@requires(order_owner)
|
|
181
|
+
async def delete(self, order_id: UUID, user: UserModel) -> None:
|
|
182
|
+
"""Delete an order the caller owns.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
order_id (UUID): The order to delete.
|
|
186
|
+
user (UserModel): The owning user.
|
|
187
|
+
"""
|
|
188
|
+
await self.repository.delete(order_id)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`async` guards may only decorate `async` functions — otherwise the coroutine
|
|
192
|
+
would never be awaited, so the import fails with `TempestPermissionError`.
|
|
193
|
+
|
|
194
|
+
## The linter catches your mistakes
|
|
195
|
+
|
|
196
|
+
Two layers, because each sees what the other cannot.
|
|
197
|
+
|
|
198
|
+
### At import time — `TempestPermissionError`
|
|
199
|
+
|
|
200
|
+
The decorator validates while the module is imported. The application **does not
|
|
201
|
+
start** with:
|
|
202
|
+
|
|
203
|
+
| Situation | Message |
|
|
204
|
+
| --- | --- |
|
|
205
|
+
| `@requires()` with no guard | `needs at least one guard` |
|
|
206
|
+
| non-callable guard | `is not callable` |
|
|
207
|
+
| guard with 2 required params | `takes 2 required params, expected 1 (user)` |
|
|
208
|
+
| `async` guard on a sync function | `is async but ... is not` |
|
|
209
|
+
| no user parameter | `no parameter annotated with a user model` |
|
|
210
|
+
| two user parameters | `several parameters are user models` |
|
|
211
|
+
|
|
212
|
+
### At call time — `GuardContractWarning`
|
|
213
|
+
|
|
214
|
+
What only shows up while running: a guard raising `ValueError` (the API would
|
|
215
|
+
answer 500 with no `code`) and a guard returning `False` (the denial would be
|
|
216
|
+
ignored). `@requires` **warns** and lets the original exception propagate — it
|
|
217
|
+
must not change the outcome of a call it is only observing.
|
|
218
|
+
|
|
219
|
+
!!! tip "Turn it into an error in tests"
|
|
220
|
+
Run the suite with
|
|
221
|
+
`-W error::tempest_fastapi_sdk.authz.GuardContractWarning` (or
|
|
222
|
+
`filterwarnings = ["error"]` in `pyproject.toml`) and a guard outside the
|
|
223
|
+
contract fails the test instead of becoming a log line.
|
|
224
|
+
|
|
225
|
+
### In CI — `tempest permissions`
|
|
226
|
+
|
|
227
|
+
What neither layer reaches: a guard whose `raise` sits behind an `if` no test
|
|
228
|
+
exercises, or a guard that is never imported. The command reads the contract off
|
|
229
|
+
the source with `ast`, without importing the application:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
tempest permissions # informative report (exit 0)
|
|
233
|
+
tempest permissions --check # exit 1 on any error (CI gate)
|
|
234
|
+
tempest permissions --check --strict # fail on warnings too
|
|
235
|
+
tempest permissions --path src --path libs
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
src/api/routers/orders.py:41 delete_order
|
|
240
|
+
error: guard-foreign-exception: guard 'order_owner' raises ValueError, which is
|
|
241
|
+
not an AppException subclass; the API layer answers it as HTTP 500 without an
|
|
242
|
+
error code
|
|
243
|
+
warning: guard-missing-annotation: guard 'order_owner' has no return annotation
|
|
244
|
+
2 finding(s), 1 error(s).
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The codes it reports:
|
|
248
|
+
|
|
249
|
+
| Code | Severity | What it means |
|
|
250
|
+
| --- | --- | --- |
|
|
251
|
+
| `no-guards` | error | `@requires()` with no guard: everything passes |
|
|
252
|
+
| `user-param-missing` | error | no parameter is a user model |
|
|
253
|
+
| `user-param-ambiguous` | error | several candidates, no `user_param=` |
|
|
254
|
+
| `guard-arity` | error | the guard does not take exactly one parameter |
|
|
255
|
+
| `guard-async-in-sync` | error | `async` guard on a sync function |
|
|
256
|
+
| `guard-returns-bool` | error | predicate-style guard: its `False` is ignored |
|
|
257
|
+
| `guard-foreign-exception` | error | raises outside the `AppException` hierarchy |
|
|
258
|
+
| `guard-never-denies` | warning | nothing in the call graph raises |
|
|
259
|
+
| `guard-missing-annotation` | warning | parameter or return unannotated |
|
|
260
|
+
| `guard-return-type` | warning | return is neither the user, `None`, nor their union |
|
|
261
|
+
| `guard-unresolved` | warning | the guard is a lambda, lives outside the scanned paths, or its name maps to several definitions |
|
|
262
|
+
|
|
263
|
+
!!! note "Reports instead of guessing"
|
|
264
|
+
A guard whose name exists in two modules becomes `guard-unresolved`, not a
|
|
265
|
+
check against the wrong definition. Same policy as `openapi-errors`:
|
|
266
|
+
over-reporting is acceptable, a confident wrong verdict is not.
|
|
267
|
+
|
|
268
|
+
## OpenAPI error-docs integration
|
|
269
|
+
|
|
270
|
+
A guard denies by raising, so its exception is as reachable as that of any
|
|
271
|
+
function the body calls. `tempest openapi-errors` reads the `@requires` guards
|
|
272
|
+
when building the reachable set:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
tempest openapi-errors --check
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
```text
|
|
279
|
+
src/api/routers/orders.py:41 DELETE /orders/{order_id}
|
|
280
|
+
undocumented: NotOrderOwnerException
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`--fix` writes `responses=error_responses(NotOrderOwnerException)` into the
|
|
284
|
+
route, like any other exception in the flow. Details in the
|
|
285
|
+
[OpenAPI errors »](openapi-errors.md) recipe.
|
|
286
|
+
|
|
287
|
+
## Auditing a route's guards
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
from tempest_fastapi_sdk import declared_guards, guarded_user_param
|
|
291
|
+
|
|
292
|
+
assert declared_guards(delete_order) == (require_active, order_owner)
|
|
293
|
+
assert guarded_user_param(delete_order) == "user"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Handy in a test asserting that every write route carries at least one guard.
|
|
297
|
+
|
|
298
|
+
## `@requires` vs. the other authorization tools
|
|
299
|
+
|
|
300
|
+
| Tool | Question it answers | Where it lives |
|
|
301
|
+
| --- | --- | --- |
|
|
302
|
+
| `make_permission_dependency` | "does the token carry `orders:write`?" | route dependency, before the handler |
|
|
303
|
+
| `has_perm` / `make_permission_checker` | "may this user act on this object?" | registry of `(user, obj) -> bool` rules |
|
|
304
|
+
| `@requires` | "does this user pass these invariants?" | any function that already receives the user |
|
|
305
|
+
|
|
306
|
+
The three compose: a guard may call `check_permission(user, "order.delete",
|
|
307
|
+
obj=order)` and pull the whole registry inside `@requires`.
|
|
308
|
+
|
|
309
|
+
## Recap
|
|
310
|
+
|
|
311
|
+
- A **guard** is `(user) -> user | None` that denies by raising an
|
|
312
|
+
`AppException`.
|
|
313
|
+
- `@requires(g1, g2)` runs the guards in order, below the route decorator.
|
|
314
|
+
- The user parameter comes from the annotation; `user_param=` breaks ties.
|
|
315
|
+
- A non-`None` return replaces the user — that is how the type narrows.
|
|
316
|
+
- Works on routers, controllers and services, sync or `async`.
|
|
317
|
+
- Misuse: `TempestPermissionError` at import, `GuardContractWarning` at call
|
|
318
|
+
time, `tempest permissions --check` in CI.
|
|
319
|
+
- Guard exceptions reach `error_responses(...)` through
|
|
320
|
+
`tempest openapi-errors`.
|