tempest-fastapi-sdk 0.87.1__tar.gz → 0.89.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.87.1 → tempest_fastapi_sdk-0.89.0}/CHANGELOG.md +44 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/CLAUDE.md +8 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/Makefile +2 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/PKG-INFO +8 -3
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/README.md +4 -2
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/storage.en.md +22 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/storage.md +22 -0
- tempest_fastapi_sdk-0.89.0/docs/ssr.en.md +286 -0
- tempest_fastapi_sdk-0.89.0/docs/ssr.md +287 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/mkdocs.yml +2 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/pyproject.toml +12 -1
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/__init__.py +1 -1
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/settings/mixins.py +35 -0
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/ssr/__init__.py +22 -0
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/ssr/_static/htmx.min.js +1 -0
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/ssr/assets.py +71 -0
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/ssr/page.py +108 -0
- tempest_fastapi_sdk-0.89.0/tempest_fastapi_sdk/ssr/response.py +118 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/storage/minio_client.py +77 -3
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/settings/test_mixins.py +2 -0
- tempest_fastapi_sdk-0.89.0/tests/ssr/test_integration.py +148 -0
- tempest_fastapi_sdk-0.89.0/tests/ssr/test_page.py +81 -0
- tempest_fastapi_sdk-0.89.0/tests/ssr/test_response.py +84 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/storage/test_minio_client.py +114 -0
- tempest_fastapi_sdk-0.89.0/tests/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/uv.lock +34 -2
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/.github/workflows/ci.yml +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/.github/workflows/docs.yml +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/.gitignore +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/.python-version +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/architecture.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/architecture.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/changelog.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/changelog.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/contributing.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/contributing.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/index.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/index.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/installation.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/installation.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/index.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/index.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/api.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/api.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/business-rules.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/business-rules.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/domain.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/domain.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/flows.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/flows.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/index.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/learning/marketplace/index.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/migration.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/migration.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/admin.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/admin.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/audit-trail.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/audit-trail.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/auth-flow.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/auth-flow.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/br-helpers.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/br-helpers.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/cache.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/cache.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/cli.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/cli.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/database.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/database.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/deploy-safety.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/deploy-safety.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/downloads.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/downloads.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/email.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/email.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/feature-flags.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/feature-flags.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/fields.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/fields.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/http-client.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/http-client.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/http.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/http.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/idempotency.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/idempotency.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/index.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/index.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/logging.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/logging.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/metrics.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/metrics.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/mfa.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/mfa.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/multi-tenant.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/multi-tenant.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/observability.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/observability.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/offline-sync.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/offline-sync.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/outbox.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/outbox.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/queue-tasks.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/queue-tasks.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/realtime.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/realtime.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/refresh-tokens.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/refresh-tokens.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/security.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/security.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/sessions.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/sessions.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/sse.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/sse.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/stored-files.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/stored-files.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/testing.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/testing.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/typing.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/typing.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/uploads.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/uploads.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/utilities.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/utilities.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/vision.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/vision.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/webpush.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/webpush.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/websocket.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/recipes/websocket.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/reference.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/reference.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/roadmap.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/roadmap.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/tutorial.en.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/docs/tutorial.md +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/mkdocs_hooks/llmstxt.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/scripts/extract_recipe.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/actions.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/auth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/config.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/discovery.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/forms.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/session.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/site.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/static/admin.css +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/detail.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/form.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/list.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/logs.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/templates/mfa.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/admin/theme.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/dependencies/auth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/graceful.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/server.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/static.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/tracing.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/guards.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/locale.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/activation.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/en-US/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_error.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/activation_success.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_error.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_form.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/templates/pt-BR/password_reset_success.html +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/auth/token_delivery.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cache/invalidation.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/Dockerfile.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/dockerignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/resources.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/config.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/db.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/main.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/new.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/secrets.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/src_layers.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/cli/user.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/controllers/base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/core/context.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/core/enums.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/core/logging.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/core/typed.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/audit.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/backup.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/connection.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/mixins.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/outbox.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/repository.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/slow_query.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/tenant.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/user_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/user_recovery_code_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/user_refresh_token_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/user_token_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/db/webpush_subscription_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/i18n.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/flags/backends.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/flags/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/flags/service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/py.typed +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/services/base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/services/file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/settings/base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sse/broker.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/sse/event_stream.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/testing/database.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/data/br_locations.json +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/download.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/email.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/fields.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/locations.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/log.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/password.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/totp.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/utils/upload.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/vision/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/vision/mapping.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/vision/schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/webpush/router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/webpush/service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_actions.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_auth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_discovery.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_forms.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_logs_nav.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_rich_filters.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_site.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_theme.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_upload_field.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/admin/test_user_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_body_size.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_cookies.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_cors.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_csrf.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_dependencies_auth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_graceful.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_handlers.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_health_router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_idempotency.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_jwt_dependency.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_logs_router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_oauth.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_prometheus.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_rate_limit.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_rate_limit_extras.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_request_id_middleware.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_role_dependency.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_server.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_static.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_tool_spec.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_tracing.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_webhooks.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/api/test_webhooks_rsa.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_cookie_delivery.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_guards.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_locale.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_mfa.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_refresh.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_refresh_db.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/auth/test_service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cache/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cache/test_decorator.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cache/test_invalidation.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cache/test_redis_manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_config.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_db.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_db_seed.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_docker_compose.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_generate.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_lint_strictness.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_main.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_secrets.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/cli/test_user.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/conftest.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/controllers/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/controllers/test_base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/core/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/core/test_context.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/core/test_enums.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/core/test_logging.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/core/test_typed.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_alembic_hooks.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_audit.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_backup.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_bulk_ops.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_connection.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_migrations.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_mixins.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_model.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_outbox.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_repository.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_safe_upgrade.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_slow_query.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/db/test_tenant.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/exceptions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/exceptions/test_exceptions.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/exceptions/test_i18n.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/flags/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/flags/test_flags.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/queue/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/queue/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/test_base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/test_cursor_pagination.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/test_link_headers.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/test_pagination.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/schemas/test_response.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/services/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/services/test_base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/services/test_file_mixin.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/sessions/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/sessions/test_sessions.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/settings/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/settings/test_base.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/sse/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/sse/test_broker.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/sse/test_event_stream.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/storage → tempest_fastapi_sdk-0.89.0/tests/ssr}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/tasks → tempest_fastapi_sdk-0.89.0/tests/storage}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/testing → tempest_fastapi_sdk-0.89.0/tests/tasks}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/tasks/test_manager.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/tasks/test_scheduler.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/utils → tempest_fastapi_sdk-0.89.0/tests/testing}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/testing/test_database.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/vision → tempest_fastapi_sdk-0.89.0/tests/utils}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_client_ip.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_datetime.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_dict.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_download.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_email.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_fields.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_http_client.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_jwt.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_lazy_extras.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_locations.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_log.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_metrics.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_opaque_token.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_password.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_regex.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_storage_backends.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_throttle.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/utils/test_upload.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/webpush → tempest_fastapi_sdk-0.89.0/tests/vision}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/vision/test_vision.py +0 -0
- {tempest_fastapi_sdk-0.87.1/tests/websockets → tempest_fastapi_sdk-0.89.0/tests/webpush}/__init__.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/webpush/test_dispatcher.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/webpush/test_router.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/webpush/test_schemas.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/webpush/test_service.py +0 -0
- {tempest_fastapi_sdk-0.87.1 → tempest_fastapi_sdk-0.89.0}/tests/websockets/test_hub_and_router.py +0 -0
|
@@ -5,6 +5,50 @@ 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.89.0] — 2026-07-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Typed server-side rendering (`tempest_fastapi_sdk.ssr`, extra
|
|
13
|
+
`[ssr]`).** A first-class SSR surface: FastAPI routes return typed
|
|
14
|
+
Python components rendered to HTML — full-stack, typed, no template
|
|
15
|
+
language.
|
|
16
|
+
- `Page` — a typed component base (`tempest_core` `Component`). Declare
|
|
17
|
+
typed fields, implement `body() -> Widget`, and optionally override
|
|
18
|
+
`shell(body)` to wrap every page in a shared header/nav/footer layout
|
|
19
|
+
inherited through normal Python inheritance. `render()` composes
|
|
20
|
+
`shell(body())` for you.
|
|
21
|
+
- `html_response(widget, *, title=None, status_code=200, htmx=False,
|
|
22
|
+
document=True, lang="pt-BR")` — renders a widget tree to a FastAPI
|
|
23
|
+
`HTMLResponse`. `document=True` emits a full HTML5 document (requires
|
|
24
|
+
`title`); `document=False` emits a bare fragment for HTMX partial
|
|
25
|
+
swaps. `htmx=True` injects a locally-served HTMX `<script>` tag
|
|
26
|
+
(never a CDN).
|
|
27
|
+
- `make_htmx_router(prefix="/_ssr")` — serves a **bundled** HTMX 2.x
|
|
28
|
+
(shipped inside the wheel) at `GET {prefix}/htmx.js` with an
|
|
29
|
+
`application/javascript` media type — CSP- and offline-friendly, no
|
|
30
|
+
external host contacted.
|
|
31
|
+
- The renderer (`tempestweb`) is imported lazily, so
|
|
32
|
+
`import tempest_fastapi_sdk` never hard-requires the extra; install
|
|
33
|
+
with `pip install "tempest-fastapi-sdk[ssr]"`.
|
|
34
|
+
|
|
35
|
+
## [0.88.0] — 2026-07-03
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- **Split-endpoint presigned URLs for MinIO/S3.** `AsyncMinIOClient`
|
|
40
|
+
gained `public_endpoint` / `public_secure` args, and `MinIOSettings`
|
|
41
|
+
the matching `MINIO_PUBLIC_ENDPOINT` / `MINIO_PUBLIC_SECURE`. When set,
|
|
42
|
+
`presigned_get_url` / `presigned_put_url` are signed against the public
|
|
43
|
+
host (so the browser can reach them) while every server-side operation
|
|
44
|
+
keeps using the internal `MINIO_ENDPOINT` (fast private network). A
|
|
45
|
+
second `minio.Minio` client signs the URLs — the host is part of the
|
|
46
|
+
SigV4 signature, so it must be signed against the public endpoint
|
|
47
|
+
rather than rewritten afterwards. Fully opt-in: without
|
|
48
|
+
`MINIO_PUBLIC_ENDPOINT`, presigned URLs are signed with `MINIO_ENDPOINT`
|
|
49
|
+
as before. A `https://` scheme (or trailing path) on the public
|
|
50
|
+
endpoint is tolerated and stripped; `https://` implies HTTPS.
|
|
51
|
+
|
|
8
52
|
## [0.87.1] — 2026-07-02
|
|
9
53
|
|
|
10
54
|
### Fixed
|
|
@@ -114,6 +114,14 @@ The SDK currently covers (Sep 2025+, post-v0.31.x):
|
|
|
114
114
|
`ort-vision-sdk`: lazy `Detector`/`Classifier`/`Segmenter` + prediction
|
|
115
115
|
schemas + `to_detection_schemas`/`to_classification_schema`/
|
|
116
116
|
`to_segmentation_schemas` mappers.
|
|
117
|
+
- **SSR** (`[ssr]` extra) — `tempest_fastapi_sdk.ssr`: typed Python
|
|
118
|
+
pages rendered to HTML via `tempestweb`'s `render_to_html` /
|
|
119
|
+
`render_document`. `Page` (typed `Component` base — `body()` +
|
|
120
|
+
overridable `shell()` layout), `html_response` (widget tree →
|
|
121
|
+
`HTMLResponse`, full document or bare HTMX fragment), and
|
|
122
|
+
`make_htmx_router` (serves a wheel-bundled HTMX 2.x locally, no CDN).
|
|
123
|
+
`tempestweb` imported lazily so `import tempest_fastapi_sdk` never
|
|
124
|
+
needs the extra.
|
|
117
125
|
- **Upload** — `UploadUtils` with pluggable backends
|
|
118
126
|
(`LocalUploadStorage`, `MinIOUploadStorage`), download helpers,
|
|
119
127
|
presigned URLs.
|
|
@@ -65,6 +65,8 @@ smoke: build ## Install the freshly built wheel in a clean venv and import the t
|
|
|
65
65
|
assert m.PasswordUtils and m.JWTUtils and m.EmailUtils and m.UploadUtils, 'utils missing'; \
|
|
66
66
|
assert m.is_valid_cpf and m.is_valid_cnpj and m.is_valid_phone_br, 'BR regex helpers missing'; \
|
|
67
67
|
print('Smoke OK · version =', m.__version__)"
|
|
68
|
+
/tmp/$(PACKAGE)-smoke/bin/python -c "from $(PACKAGE).ssr import Page, html_response, make_htmx_router; \
|
|
69
|
+
print('SSR extra OK ·', Page.__name__, html_response.__name__, make_htmx_router.__name__)"
|
|
68
70
|
@rm -rf /tmp/$(PACKAGE)-smoke
|
|
69
71
|
|
|
70
72
|
version: ## Print the version recorded in pyproject.toml and __init__.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempest-fastapi-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.89.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
|
|
@@ -59,6 +59,7 @@ Requires-Dist: pywebpush>=2.0.0; extra == 'all'
|
|
|
59
59
|
Requires-Dist: redis>=5.0.0; extra == 'all'
|
|
60
60
|
Requires-Dist: taskiq-aio-pika>=0.4.0; extra == 'all'
|
|
61
61
|
Requires-Dist: taskiq>=0.11.0; extra == 'all'
|
|
62
|
+
Requires-Dist: tempestweb>=0.9.0; extra == 'all'
|
|
62
63
|
Provides-Extra: auth
|
|
63
64
|
Requires-Dist: bcrypt>=5.0.0; extra == 'auth'
|
|
64
65
|
Requires-Dist: pyjwt>=2.12.1; extra == 'auth'
|
|
@@ -91,6 +92,8 @@ Provides-Extra: queue
|
|
|
91
92
|
Requires-Dist: faststream[rabbit]>=0.7.1; extra == 'queue'
|
|
92
93
|
Provides-Extra: sqlite
|
|
93
94
|
Requires-Dist: aiosqlite>=0.20.0; extra == 'sqlite'
|
|
95
|
+
Provides-Extra: ssr
|
|
96
|
+
Requires-Dist: tempestweb>=0.9.0; extra == 'ssr'
|
|
94
97
|
Provides-Extra: tasks
|
|
95
98
|
Requires-Dist: taskiq-aio-pika>=0.4.0; extra == 'tasks'
|
|
96
99
|
Requires-Dist: taskiq>=0.11.0; extra == 'tasks'
|
|
@@ -116,7 +119,7 @@ Description-Content-Type: text/markdown
|
|
|
116
119
|
|
|
117
120
|
> 💡 `uv run mkdocs serve` (ou `make docs-serve`) é só para preview local — em produção use as URLs do GitHub Pages acima. / For local preview only — in production use the GitHub Pages URLs above.
|
|
118
121
|
|
|
119
|
-
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
122
|
+
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
120
123
|
|
|
121
124
|
The goal is to start every new backend with the same opinionated foundation already in place — no copy-pasting `BaseModel`, no rewriting the same CRUD repository, no re-inventing the exception envelope.
|
|
122
125
|
|
|
@@ -223,6 +226,7 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
|
|
|
223
226
|
| `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
|
|
224
227
|
| `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA endpoints on the bundled auth flow |
|
|
225
228
|
| `[vision]` | `ort-vision-sdk` | `Detector` / `Classifier` / `Segmenter` (ONNX) + prediction schemas |
|
|
229
|
+
| `[ssr]` | `tempestweb` | `Page`, `html_response`, `make_htmx_router` — typed Python pages rendered to HTML |
|
|
226
230
|
| `[otel]` | `opentelemetry-sdk` + OTLP/gRPC exporter + FastAPI/SQLAlchemy/httpx instrumentors | `setup_tracing` — distributed tracing |
|
|
227
231
|
| `[sqlite]` | `aiosqlite` | SQLite async driver for `sqlite+aiosqlite://` URLs (dev default) |
|
|
228
232
|
| `[postgres]` | `asyncpg` | PostgreSQL async driver for `postgresql+asyncpg://` URLs (production) |
|
|
@@ -264,10 +268,11 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
264
268
|
| `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
|
|
265
269
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
266
270
|
| `tempest_fastapi_sdk.vision` *(extra: `[vision]`)* | `Detector`, `Classifier`, `Segmenter` (ONNX, lazy), `DetectionSchema`/`ClassificationSchema`/`SegmentationSchema`/`BoundingBoxSchema`/`ClassProbabilitySchema`, `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas` |
|
|
271
|
+
| `tempest_fastapi_sdk.ssr` *(extra: `[ssr]`)* | `Page` (typed component base), `html_response` (widget tree → `HTMLResponse`, full document or HTMX fragment), `make_htmx_router` (serves bundled HTMX locally, no CDN) |
|
|
267
272
|
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
268
273
|
| `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
|
|
269
274
|
|
|
270
|
-
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks` and `tempest_fastapi_sdk.
|
|
275
|
+
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks`, `tempest_fastapi_sdk.vision` and `tempest_fastapi_sdk.ssr` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
271
276
|
|
|
272
277
|
---
|
|
273
278
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
> 💡 `uv run mkdocs serve` (ou `make docs-serve`) é só para preview local — em produção use as URLs do GitHub Pages acima. / For local preview only — in production use the GitHub Pages URLs above.
|
|
12
12
|
|
|
13
|
-
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
13
|
+
Shared FastAPI/SQLAlchemy/Pydantic building blocks used across Tempest projects: base schemas, ORM model, async repository, pagination, settings, exceptions, Alembic helper, FastStream/TaskIQ broker managers, Redis cache, Server-Sent Events, Web Push, a Django-style **admin site** (`AdminSite` + `AdminModel`), **typed SSR pages** (`Page` + `html_response`, HTMX-ready), and the utility classes (`PasswordUtils`, `JWTUtils`, `EmailUtils`, `UploadUtils`, `DownloadUtils`, `MetricsUtils`, `LogUtils`).
|
|
14
14
|
|
|
15
15
|
The goal is to start every new backend with the same opinionated foundation already in place — no copy-pasting `BaseModel`, no rewriting the same CRUD repository, no re-inventing the exception envelope.
|
|
16
16
|
|
|
@@ -117,6 +117,7 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
|
|
|
117
117
|
| `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
|
|
118
118
|
| `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA endpoints on the bundled auth flow |
|
|
119
119
|
| `[vision]` | `ort-vision-sdk` | `Detector` / `Classifier` / `Segmenter` (ONNX) + prediction schemas |
|
|
120
|
+
| `[ssr]` | `tempestweb` | `Page`, `html_response`, `make_htmx_router` — typed Python pages rendered to HTML |
|
|
120
121
|
| `[otel]` | `opentelemetry-sdk` + OTLP/gRPC exporter + FastAPI/SQLAlchemy/httpx instrumentors | `setup_tracing` — distributed tracing |
|
|
121
122
|
| `[sqlite]` | `aiosqlite` | SQLite async driver for `sqlite+aiosqlite://` URLs (dev default) |
|
|
122
123
|
| `[postgres]` | `asyncpg` | PostgreSQL async driver for `postgresql+asyncpg://` URLs (production) |
|
|
@@ -158,10 +159,11 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
|
|
|
158
159
|
| `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
|
|
159
160
|
| `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
|
|
160
161
|
| `tempest_fastapi_sdk.vision` *(extra: `[vision]`)* | `Detector`, `Classifier`, `Segmenter` (ONNX, lazy), `DetectionSchema`/`ClassificationSchema`/`SegmentationSchema`/`BoundingBoxSchema`/`ClassProbabilitySchema`, `to_detection_schemas`/`to_classification_schema`/`to_segmentation_schemas` |
|
|
162
|
+
| `tempest_fastapi_sdk.ssr` *(extra: `[ssr]`)* | `Page` (typed component base), `html_response` (widget tree → `HTMLResponse`, full document or HTMX fragment), `make_htmx_router` (serves bundled HTMX locally, no CDN) |
|
|
161
163
|
| `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, validated field types (`PositiveIntField`, `NonNegativeIntField`, `CentsField`, `PortField`, `PositiveFloatField`, `NonNegativeFloatField`, `PercentField`, `RatioField`, `LatitudeField`, `LongitudeField`, `PriceField`, `NonEmptyStrField`, `SlugField`, `HexColorField`), BR regex helpers (`CPFField`, `CNPJField`, `CPFOrCNPJField`, `PhoneBRField`, `CEPField` — old names without the suffix kept as deprecated aliases — `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`), BR states/cities (`UF`, `Region`, `StateBR`, `CityBR`, `ChoiceBR`, `UFField`, `CityNameField`, `list_states`, `get_state`, `cities_by_uf`, `states_by_region`, `uf_choices`/`region_choices`/`city_choices`, `is_valid_uf`/`normalize_uf`, `is_valid_city`/`normalize_city`) |
|
|
162
164
|
| `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
|
|
163
165
|
|
|
164
|
-
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks` and `tempest_fastapi_sdk.
|
|
166
|
+
Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue`, `tempest_fastapi_sdk.tasks`, `tempest_fastapi_sdk.vision` and `tempest_fastapi_sdk.ssr` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
|
|
165
167
|
|
|
166
168
|
---
|
|
167
169
|
|
|
@@ -180,6 +180,28 @@ async def get_download_url(key: str) -> dict[str, str]:
|
|
|
180
180
|
return {"url": url}
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
### Separate public endpoint for presigned URLs *(v0.88.0+)*
|
|
184
|
+
|
|
185
|
+
Common production shape: the backend talks to MinIO over a **fast private network** (`servus-storage:9000`, no TLS), but the **browser** can't reach that host — it needs a **public HTTPS** host. If you sign the presigned URL with the internal endpoint, the link carries `servus-storage:9000` and the browser can't open it.
|
|
186
|
+
|
|
187
|
+
Fix: `MINIO_PUBLIC_ENDPOINT`. Presigned URLs (`presigned_get_url` / `presigned_put_url`) are then **signed against the public host**, while **every server→MinIO operation keeps using the internal endpoint**.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# .env
|
|
191
|
+
MINIO_ENDPOINT=servus-storage:9000 # internal Docker network (ops)
|
|
192
|
+
MINIO_SECURE=false
|
|
193
|
+
MINIO_PUBLIC_ENDPOINT=https://storage.example.com # browser (presigned)
|
|
194
|
+
# MINIO_PUBLIC_SECURE=true # optional; https:// already implies it
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
!!! info "Why two clients, not a host replace"
|
|
198
|
+
A presigned URL is SigV4-signed including the `Host` header. Rewriting the host **after** signing invalidates the signature. So the SDK keeps a second `minio.Minio` (same credentials) whose only job is to **sign** against the public host — the internal `AsyncMinIOClient.client` still does put/get/stat/ensure_bucket over the private network.
|
|
199
|
+
|
|
200
|
+
!!! tip "Without `MINIO_PUBLIC_ENDPOINT`"
|
|
201
|
+
Unchanged behaviour: presigned URLs are signed with `MINIO_ENDPOINT` (single-endpoint mode). The split is fully opt-in.
|
|
202
|
+
|
|
203
|
+
The public host's proxy must route to the **MinIO S3 API (port 9000)** over TLS and forward the correct `Host` (the signature validates it).
|
|
204
|
+
|
|
183
205
|
### List objects by prefix
|
|
184
206
|
|
|
185
207
|
```python
|
|
@@ -180,6 +180,28 @@ async def get_download_url(key: str) -> dict[str, str]:
|
|
|
180
180
|
return {"url": url}
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
### Endpoint público separado para presigned URLs *(v0.88.0+)*
|
|
184
|
+
|
|
185
|
+
Cenário comum em produção: o backend fala com o MinIO por uma **rede privada rápida** (`servus-storage:9000`, sem TLS), mas o **browser** não alcança esse host — precisa de um host **público com HTTPS**. Se você assinar a presigned URL com o endpoint interno, o link vem com `servus-storage:9000` e o navegador não abre.
|
|
186
|
+
|
|
187
|
+
Solução: `MINIO_PUBLIC_ENDPOINT`. As presigned URLs (`presigned_get_url` / `presigned_put_url`) passam a ser **assinadas contra o host público**, enquanto **todas as operações servidor→MinIO continuam no endpoint interno**.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# .env
|
|
191
|
+
MINIO_ENDPOINT=servus-storage:9000 # rede interna Docker (ops)
|
|
192
|
+
MINIO_SECURE=false
|
|
193
|
+
MINIO_PUBLIC_ENDPOINT=https://storage.example.com # browser (presigned)
|
|
194
|
+
# MINIO_PUBLIC_SECURE=true # opcional; https:// já implica true
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
!!! info "Por que dois clients e não um replace de host"
|
|
198
|
+
A presigned URL é assinada (SigV4) incluindo o header `Host`. Trocar o host **depois** de assinar invalida a assinatura. Por isso o SDK mantém um segundo `minio.Minio` (mesmas credenciais) só para **assinar** contra o host público — o `AsyncMinIOClient.client` interno segue fazendo put/get/stat/ensure_bucket pela rede privada.
|
|
199
|
+
|
|
200
|
+
!!! tip "Sem `MINIO_PUBLIC_ENDPOINT`"
|
|
201
|
+
Comportamento inalterado: presigned URLs são assinadas com `MINIO_ENDPOINT` (modo endpoint único). O split é 100% opt-in.
|
|
202
|
+
|
|
203
|
+
O proxy do host público precisa rotear para a **API S3 do MinIO (porta 9000)** com TLS e repassar o `Host` correto (a assinatura valida o host).
|
|
204
|
+
|
|
183
205
|
### Listar objetos por prefixo
|
|
184
206
|
|
|
185
207
|
```python
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# SSR: typed Python pages rendered to HTML
|
|
2
|
+
|
|
3
|
+
Your FastAPI service, full-stack, **typed**, with no template language. 🚀
|
|
4
|
+
|
|
5
|
+
The SDK's SSR (Server-Side Rendering) layer lets you describe pages as
|
|
6
|
+
**typed Python components** and return them from a route already rendered
|
|
7
|
+
to HTML. No Jinja, no loose strings: the same type checker that covers
|
|
8
|
+
your schemas and services now covers your UI too.
|
|
9
|
+
|
|
10
|
+
!!! info "What you'll need"
|
|
11
|
+
The SSR layer lives in the optional `[ssr]` extra, which pulls in the
|
|
12
|
+
[`tempestweb`](https://pypi.org/project/tempestweb/) renderer (and,
|
|
13
|
+
transitively, `tempest-core` with the typed widgets).
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install "tempest-fastapi-sdk[ssr]"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Why this exists
|
|
20
|
+
|
|
21
|
+
In a traditional API you return JSON and a separate front-end draws the
|
|
22
|
+
screen. When all you need are server-driven pages (an internal panel, an
|
|
23
|
+
onboarding flow, a landing page), spinning up a whole SPA is dead weight.
|
|
24
|
+
|
|
25
|
+
The classic alternative — a templating engine — drops you out of the typed
|
|
26
|
+
world: the template is a string, the editor can't help you, and a field
|
|
27
|
+
renamed in the schema only breaks in production.
|
|
28
|
+
|
|
29
|
+
The SSR layer solves this by keeping **everything in typed Python**:
|
|
30
|
+
|
|
31
|
+
- You declare the page as a class (`Page`) with typed fields.
|
|
32
|
+
- You build the body with widgets (`Column`, `Row`, `Text`, `Button`, ...).
|
|
33
|
+
- You return `html_response(...)` from the route — and get an `HTMLResponse`.
|
|
34
|
+
|
|
35
|
+
## Minimal complete example
|
|
36
|
+
|
|
37
|
+
This is a complete, runnable program. Save it as `main.py`, install the
|
|
38
|
+
extra, and run it with `uvicorn main:app`.
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from tempest_core import Column, Text, Widget
|
|
42
|
+
from fastapi import FastAPI
|
|
43
|
+
|
|
44
|
+
from tempest_fastapi_sdk.ssr import Page, html_response
|
|
45
|
+
|
|
46
|
+
app: FastAPI = FastAPI()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class HomePage(Page):
|
|
50
|
+
"""The home page, with a single typed field."""
|
|
51
|
+
|
|
52
|
+
user: str
|
|
53
|
+
|
|
54
|
+
def body(self) -> Widget:
|
|
55
|
+
"""The page's main content."""
|
|
56
|
+
return Column(
|
|
57
|
+
tag="main",
|
|
58
|
+
children=[
|
|
59
|
+
Text(content=f"Hello, {self.user}!", tag="h1"),
|
|
60
|
+
Text(content="Welcome to your typed app.", tag="p"),
|
|
61
|
+
],
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@app.get("/")
|
|
66
|
+
def home() -> object:
|
|
67
|
+
"""Render HomePage as a full HTML document."""
|
|
68
|
+
return html_response(HomePage(title="Home", user="Ana"), title="Home")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Open `http://127.0.0.1:8000/` and you get a full HTML5 document with
|
|
72
|
+
`<!doctype html>`, `<title>Home</title>`, and a `<main>` body — all
|
|
73
|
+
generated from the classes above.
|
|
74
|
+
|
|
75
|
+
## Piece by piece
|
|
76
|
+
|
|
77
|
+
### The `Page` class
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
class HomePage(Page):
|
|
81
|
+
user: str
|
|
82
|
+
|
|
83
|
+
def body(self) -> Widget:
|
|
84
|
+
return Column(tag="main", children=[Text(content=f"Hello, {self.user}!")])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`Page` is a **`tempest_core` component** (a Pydantic model). That means the
|
|
88
|
+
page's data are **typed fields** — here, `user: str`. The inherited
|
|
89
|
+
`title: str` field feeds the document `<title>`.
|
|
90
|
+
|
|
91
|
+
You implement **`body()`**, which returns the widget tree for the main
|
|
92
|
+
content. It is the only required method.
|
|
93
|
+
|
|
94
|
+
!!! tip "Semantic tags"
|
|
95
|
+
Every widget accepts `tag=` and `attrs=`. Use `tag="main"`,
|
|
96
|
+
`tag="h1"`, `tag="nav"` to emit semantic HTML instead of the neutral
|
|
97
|
+
defaults (`<div>` / `<span>`).
|
|
98
|
+
|
|
99
|
+
### The `html_response` function
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
return html_response(HomePage(title="Home", user="Ana"), title="Home")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`html_response` renders the tree and returns a FastAPI `HTMLResponse`.
|
|
106
|
+
Its signature:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
def html_response(
|
|
110
|
+
widget: Widget,
|
|
111
|
+
*,
|
|
112
|
+
title: str | None = None,
|
|
113
|
+
status_code: int = 200,
|
|
114
|
+
htmx: bool = False,
|
|
115
|
+
document: bool = True,
|
|
116
|
+
lang: str = "pt-BR",
|
|
117
|
+
) -> HTMLResponse: ...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- **`document=True`** (default) → full HTML5 document. Requires `title`
|
|
121
|
+
(raises `ValueError` if `title is None`).
|
|
122
|
+
- **`document=False`** → bare HTML fragment (no `<!doctype>`), ideal for
|
|
123
|
+
partial swaps with HTMX.
|
|
124
|
+
- **`status_code`** → passed through to the `HTMLResponse`.
|
|
125
|
+
- **`htmx=True`** → inject the HTMX `<script>` **served locally** (never
|
|
126
|
+
from a CDN — see below).
|
|
127
|
+
|
|
128
|
+
!!! warning "`title` is required for documents"
|
|
129
|
+
Calling `html_response(page)` with `document=True` (the default) and
|
|
130
|
+
no `title` raises `ValueError`. For fragments (`document=False`),
|
|
131
|
+
`title` is ignored.
|
|
132
|
+
|
|
133
|
+
## Shared layout with `shell()`
|
|
134
|
+
|
|
135
|
+
Every page usually shares the same header, navigation, and footer. Instead
|
|
136
|
+
of repeating it, override **`shell()`** on a base page and inherit through
|
|
137
|
+
normal Python inheritance.
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from tempest_core import Column, Row, Text, Widget
|
|
141
|
+
|
|
142
|
+
from tempest_fastapi_sdk.ssr import Page, html_response
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class BasePage(Page):
|
|
146
|
+
"""Shared layout: navigation bar + main area."""
|
|
147
|
+
|
|
148
|
+
def shell(self, body: Widget) -> Widget:
|
|
149
|
+
return Column(
|
|
150
|
+
tag="body",
|
|
151
|
+
children=[
|
|
152
|
+
Row(tag="nav", children=[Text(content="MyApp")]),
|
|
153
|
+
Column(tag="main", children=[body]),
|
|
154
|
+
],
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class DashboardPage(BasePage):
|
|
159
|
+
"""Inherits the navigation, defines only its own body."""
|
|
160
|
+
|
|
161
|
+
def body(self) -> Widget:
|
|
162
|
+
return Text(content="Dashboard", tag="h2")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class ReportsPage(BasePage):
|
|
166
|
+
"""Same navigation, different body."""
|
|
167
|
+
|
|
168
|
+
def body(self) -> Widget:
|
|
169
|
+
return Text(content="Reports", tag="h2")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`render()` (the component hook) already composes `shell(body())` for you —
|
|
173
|
+
**do not override `render()`**; override `body()` and, optionally,
|
|
174
|
+
`shell()`.
|
|
175
|
+
|
|
176
|
+
!!! note "How composition works"
|
|
177
|
+
`Page.render()` returns `self.shell(self.body())`. The renderer expands
|
|
178
|
+
components recursively, so a page is just another widget in the tree.
|
|
179
|
+
|
|
180
|
+
## HTMX served locally (no CDN)
|
|
181
|
+
|
|
182
|
+
For server-driven interactivity without writing JavaScript, the SDK bundles
|
|
183
|
+
HTMX 2.x **inside the package** and serves it from your own app — CSP-
|
|
184
|
+
friendly and offline-capable. No CDN.
|
|
185
|
+
|
|
186
|
+
Mount the router and flip `htmx=True`:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from tempest_fastapi_sdk.ssr import make_htmx_router
|
|
190
|
+
|
|
191
|
+
app.include_router(make_htmx_router()) # serves GET /_ssr/htmx.js
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
When you call `html_response(page, title=..., htmx=True)`, the generated
|
|
195
|
+
document points at `/_ssr/htmx.js` (the same path served by the router),
|
|
196
|
+
never at `https://unpkg.com/...`.
|
|
197
|
+
|
|
198
|
+
### Recipe: server-driven counter with HTMX
|
|
199
|
+
|
|
200
|
+
A button that increments a counter on the server and swaps just a fragment —
|
|
201
|
+
no JavaScript. Complete program:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from tempest_core import Button, Column, Text, Widget
|
|
205
|
+
from fastapi import FastAPI
|
|
206
|
+
|
|
207
|
+
from tempest_fastapi_sdk.ssr import Page, html_response, make_htmx_router
|
|
208
|
+
|
|
209
|
+
app: FastAPI = FastAPI()
|
|
210
|
+
app.include_router(make_htmx_router())
|
|
211
|
+
|
|
212
|
+
_count: int = 0
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class CounterFragment(Page):
|
|
216
|
+
"""The fragment swapped on each click."""
|
|
217
|
+
|
|
218
|
+
value: int
|
|
219
|
+
|
|
220
|
+
def body(self) -> Widget:
|
|
221
|
+
return Column(
|
|
222
|
+
attrs={"id": "counter"},
|
|
223
|
+
children=[
|
|
224
|
+
Text(content=f"Total: {self.value}", tag="p"),
|
|
225
|
+
Button(
|
|
226
|
+
label="Increment",
|
|
227
|
+
attrs={
|
|
228
|
+
"hx-post": "/increment",
|
|
229
|
+
"hx-target": "#counter",
|
|
230
|
+
"hx-swap": "outerHTML",
|
|
231
|
+
},
|
|
232
|
+
),
|
|
233
|
+
],
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class CounterPage(Page):
|
|
238
|
+
"""The full page that loads HTMX and shows the counter."""
|
|
239
|
+
|
|
240
|
+
value: int
|
|
241
|
+
|
|
242
|
+
def body(self) -> Widget:
|
|
243
|
+
return CounterFragment(title="", value=self.value)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@app.get("/")
|
|
247
|
+
def index() -> object:
|
|
248
|
+
"""Full document, with the local HTMX loaded (htmx=True)."""
|
|
249
|
+
return html_response(
|
|
250
|
+
CounterPage(title="Counter", value=_count), title="Counter", htmx=True
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@app.post("/increment")
|
|
255
|
+
def increment() -> object:
|
|
256
|
+
"""Increment and return only the fragment (document=False)."""
|
|
257
|
+
global _count
|
|
258
|
+
_count += 1
|
|
259
|
+
return html_response(CounterFragment(title="", value=_count), document=False)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
How it works:
|
|
263
|
+
|
|
264
|
+
1. `GET /` returns the **full document** (`document=True`, `htmx=True`), so
|
|
265
|
+
the local HTMX is loaded.
|
|
266
|
+
2. The button has `hx-post="/increment"` and `hx-swap="outerHTML"`.
|
|
267
|
+
3. `POST /increment` returns only the **fragment** (`document=False`), and
|
|
268
|
+
HTMX swaps the `<div id="counter">` in place.
|
|
269
|
+
|
|
270
|
+
!!! check "Safe by default"
|
|
271
|
+
All text is escaped on render. A `Text(content="<script>")` becomes
|
|
272
|
+
`<script>` in the final HTML — no accidental injection.
|
|
273
|
+
|
|
274
|
+
## Recap
|
|
275
|
+
|
|
276
|
+
- **`Page`** — typed component; declare fields, implement `body()`,
|
|
277
|
+
optionally override `shell()` for a shared layout. Do not override
|
|
278
|
+
`render()`.
|
|
279
|
+
- **`html_response(widget, *, title, status_code, htmx, document, lang)`** —
|
|
280
|
+
renders and returns an `HTMLResponse`. `document=True` requires `title`;
|
|
281
|
+
`document=False` returns a fragment for HTMX swaps.
|
|
282
|
+
- **`make_htmx_router(prefix="/_ssr")`** — serves the bundled HTMX locally
|
|
283
|
+
at `GET /_ssr/htmx.js`; combine with `htmx=True`.
|
|
284
|
+
- Everything lives in the `[ssr]` extra
|
|
285
|
+
(`pip install "tempest-fastapi-sdk[ssr]"`), loaded on demand —
|
|
286
|
+
`import tempest_fastapi_sdk` never requires the extra.
|