tempest-fastapi-sdk 0.76.0__tar.gz → 0.78.0__tar.gz

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