svc-infra 0.1.630__tar.gz → 0.1.631__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.

Potentially problematic release.


This version of svc-infra might be problematic. Click here for more details.

Files changed (346) hide show
  1. {svc_infra-0.1.630 → svc_infra-0.1.631}/PKG-INFO +1 -1
  2. {svc_infra-0.1.630 → svc_infra-0.1.631}/pyproject.toml +1 -1
  3. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/jobs.py +14 -2
  4. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/__init__.py +4 -0
  5. svc_infra-0.1.631/src/svc_infra/cache/add.py +158 -0
  6. svc_infra-0.1.631/src/svc_infra/docs/cache.md +76 -0
  7. svc_infra-0.1.630/src/svc_infra/docs/cache.md +0 -18
  8. {svc_infra-0.1.630 → svc_infra-0.1.631}/README.md +0 -0
  9. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/__init__.py +0 -0
  10. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/README.md +0 -0
  11. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/__init__.py +0 -0
  12. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/alembic.py +0 -0
  13. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/models.py +0 -0
  14. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/provider/__init__.py +0 -0
  15. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/provider/aiydan.py +0 -0
  16. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/provider/base.py +0 -0
  17. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/provider/registry.py +0 -0
  18. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/provider/stripe.py +0 -0
  19. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/schemas.py +0 -0
  20. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/service.py +0 -0
  21. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/apf_payments/settings.py +0 -0
  22. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/__init__.py +0 -0
  23. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/__init__.py +0 -0
  24. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/apf_payments/__init__.py +0 -0
  25. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/apf_payments/router.py +0 -0
  26. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/apf_payments/setup.py +0 -0
  27. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/__init__.py +0 -0
  28. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/_cookies.py +0 -0
  29. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/add.py +0 -0
  30. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/gaurd.py +0 -0
  31. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/__init__.py +0 -0
  32. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/models.py +0 -0
  33. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +0 -0
  34. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/router.py +0 -0
  35. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/security.py +0 -0
  36. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/utils.py +0 -0
  37. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/mfa/verify.py +0 -0
  38. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/policy.py +0 -0
  39. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/providers.py +0 -0
  40. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/routers/__init__.py +0 -0
  41. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
  42. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +0 -0
  43. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +0 -0
  44. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/routers/session_router.py +0 -0
  45. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/security.py +0 -0
  46. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/sender.py +0 -0
  47. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/settings.py +0 -0
  48. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/auth/state.py +0 -0
  49. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/billing/router.py +0 -0
  50. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/billing/setup.py +0 -0
  51. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/cache/__init__.py +0 -0
  52. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/cache/add.py +0 -0
  53. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/__init__.py +0 -0
  54. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/http.py +0 -0
  55. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -0
  56. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/nosql/mongo/__init__.py +0 -0
  57. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +0 -0
  58. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +0 -0
  59. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
  60. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/README.md +0 -0
  61. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/__init__.py +0 -0
  62. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/add.py +0 -0
  63. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/crud_router.py +0 -0
  64. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/health.py +0 -0
  65. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/session.py +0 -0
  66. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/db/sql/users.py +0 -0
  67. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +0 -0
  68. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/docs/__init__.py +0 -0
  69. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/docs/add.py +0 -0
  70. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/docs/landing.py +0 -0
  71. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/docs/scoped.py +0 -0
  72. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/__init__.py +0 -0
  73. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/dualize.py +0 -0
  74. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/protected.py +0 -0
  75. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/public.py +0 -0
  76. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/router.py +0 -0
  77. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
  78. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/dx.py +0 -0
  79. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/ease.py +0 -0
  80. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/http/__init__.py +0 -0
  81. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/http/concurrency.py +0 -0
  82. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/http/conditional.py +0 -0
  83. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
  84. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/__init__.py +0 -0
  85. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/debug.py +0 -0
  86. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/errors/__init__.py +0 -0
  87. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +0 -0
  88. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +0 -0
  89. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +0 -0
  90. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/graceful_shutdown.py +0 -0
  91. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -0
  92. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +0 -0
  93. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +0 -0
  94. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -0
  95. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +0 -0
  96. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/request_id.py +0 -0
  97. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +0 -0
  98. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/middleware/timeout.py +0 -0
  99. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/__init__.py +0 -0
  100. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/apply.py +0 -0
  101. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/conventions.py +0 -0
  102. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/models.py +0 -0
  103. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/mutators.py +0 -0
  104. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/pipeline.py +0 -0
  105. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/responses.py +0 -0
  106. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/openapi/security.py +0 -0
  107. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/ops/add.py +0 -0
  108. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/pagination.py +0 -0
  109. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/paths/__init__.py +0 -0
  110. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
  111. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
  112. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
  113. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/paths/user.py +0 -0
  114. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/routers/__init__.py +0 -0
  115. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
  116. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/setup.py +0 -0
  117. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/tenancy/add.py +0 -0
  118. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/api/fastapi/tenancy/context.py +0 -0
  119. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/README.md +0 -0
  120. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/__init__.py +0 -0
  121. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/env.py +0 -0
  122. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/logging/__init__.py +0 -0
  123. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/logging/add.py +0 -0
  124. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/logging/filter.py +0 -0
  125. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/logging/formats.py +0 -0
  126. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/app/root.py +0 -0
  127. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/__init__.py +0 -0
  128. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/async_service.py +0 -0
  129. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/models.py +0 -0
  130. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/quotas.py +0 -0
  131. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/schemas.py +0 -0
  132. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/billing/service.py +0 -0
  133. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/bundled_docs/README.md +0 -0
  134. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/bundled_docs/__init__.py +0 -0
  135. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/bundled_docs/getting-started.md +0 -0
  136. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/README.md +0 -0
  137. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/backend.py +0 -0
  138. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/decorators.py +0 -0
  139. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/demo.py +0 -0
  140. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/keys.py +0 -0
  141. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/recache.py +0 -0
  142. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/resources.py +0 -0
  143. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/tags.py +0 -0
  144. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/ttl.py +0 -0
  145. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cache/utils.py +0 -0
  146. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/__init__.py +0 -0
  147. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/__main__.py +0 -0
  148. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/__init__.py +0 -0
  149. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/__init__.py +0 -0
  150. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/nosql/__init__.py +0 -0
  151. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +0 -0
  152. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/nosql/mongo/__init__.py +0 -0
  153. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +0 -0
  154. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +0 -0
  155. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/sql/__init__.py +0 -0
  156. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +0 -0
  157. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +0 -0
  158. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +0 -0
  159. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/docs/docs_cmds.py +0 -0
  160. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/dx/__init__.py +0 -0
  161. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/dx/dx_cmds.py +0 -0
  162. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/help.py +0 -0
  163. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
  164. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +0 -0
  165. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/obs/__init__.py +0 -0
  166. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/obs/obs_cmds.py +0 -0
  167. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/sdk/__init__.py +0 -0
  168. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/cmds/sdk/sdk_cmds.py +0 -0
  169. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/foundation/__init__.py +0 -0
  170. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/foundation/runner.py +0 -0
  171. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/cli/foundation/typer_bootstrap.py +0 -0
  172. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/data/add.py +0 -0
  173. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/data/backup.py +0 -0
  174. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/data/erasure.py +0 -0
  175. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/data/fixtures.py +0 -0
  176. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/data/retention.py +0 -0
  177. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/__init__.py +0 -0
  178. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/crud_schema.py +0 -0
  179. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/inbox.py +0 -0
  180. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/__init__.py +0 -0
  181. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/base.py +0 -0
  182. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/constants.py +0 -0
  183. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/core.py +0 -0
  184. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/indexes.py +0 -0
  185. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/management.py +0 -0
  186. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/README.md +0 -0
  187. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/__init__.py +0 -0
  188. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/client.py +0 -0
  189. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/settings.py +0 -0
  190. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/templates/__init__.py +0 -0
  191. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
  192. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
  193. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
  194. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/repository.py +0 -0
  195. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/resource.py +0 -0
  196. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/scaffold.py +0 -0
  197. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/service.py +0 -0
  198. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/service_with_hooks.py +0 -0
  199. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/types.py +0 -0
  200. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/nosql/utils.py +0 -0
  201. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/outbox.py +0 -0
  202. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/README.md +0 -0
  203. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/__init__.py +0 -0
  204. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/apikey.py +0 -0
  205. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/authref.py +0 -0
  206. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/base.py +0 -0
  207. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/constants.py +0 -0
  208. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/core.py +0 -0
  209. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/management.py +0 -0
  210. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/repository.py +0 -0
  211. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/resource.py +0 -0
  212. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/scaffold.py +0 -0
  213. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/service.py +0 -0
  214. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/service_with_hooks.py +0 -0
  215. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/__init__.py +0 -0
  216. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/models_schemas/__init__.py +0 -0
  217. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +0 -0
  218. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
  219. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
  220. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
  221. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/setup/__init__.py +0 -0
  222. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
  223. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +0 -0
  224. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +0 -0
  225. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
  226. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/tenant.py +0 -0
  227. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/types.py +0 -0
  228. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/uniq.py +0 -0
  229. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/uniq_hooks.py +0 -0
  230. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/utils.py +0 -0
  231. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/sql/versioning.py +0 -0
  232. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/db/utils.py +0 -0
  233. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/acceptance-matrix.md +0 -0
  234. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/acceptance.md +0 -0
  235. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0002-background-jobs-and-scheduling.md +0 -0
  236. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0003-webhooks-framework.md +0 -0
  237. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0004-tenancy-model.md +0 -0
  238. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0005-data-lifecycle.md +0 -0
  239. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0006-ops-slos-and-metrics.md +0 -0
  240. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0007-docs-and-sdks.md +0 -0
  241. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0008-billing-primitives.md +0 -0
  242. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0009-acceptance-harness.md +0 -0
  243. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/adr/0010-timeouts-and-resource-limits.md +0 -0
  244. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/api.md +0 -0
  245. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/auth.md +0 -0
  246. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/billing.md +0 -0
  247. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/cli.md +0 -0
  248. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/contributing.md +0 -0
  249. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/data-lifecycle.md +0 -0
  250. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/database.md +0 -0
  251. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/docs-and-sdks.md +0 -0
  252. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/environment.md +0 -0
  253. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/getting-started.md +0 -0
  254. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/idempotency.md +0 -0
  255. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/jobs.md +0 -0
  256. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/observability.md +0 -0
  257. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/ops.md +0 -0
  258. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/rate-limiting.md +0 -0
  259. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/repo-review.md +0 -0
  260. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/security.md +0 -0
  261. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/tenancy.md +0 -0
  262. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/timeouts-and-resource-limits.md +0 -0
  263. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/docs/webhooks.md +0 -0
  264. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/dx/add.py +0 -0
  265. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/dx/changelog.py +0 -0
  266. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/dx/checks.py +0 -0
  267. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/http/__init__.py +0 -0
  268. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/http/client.py +0 -0
  269. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/builtins/outbox_processor.py +0 -0
  270. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/builtins/webhook_delivery.py +0 -0
  271. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/easy.py +0 -0
  272. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/loader.py +0 -0
  273. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/queue.py +0 -0
  274. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/redis_queue.py +0 -0
  275. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/runner.py +0 -0
  276. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/scheduler.py +0 -0
  277. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/jobs/worker.py +0 -0
  278. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/mcp/__init__.py +0 -0
  279. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/mcp/svc_infra_mcp.py +0 -0
  280. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/README.md +0 -0
  281. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/__init__.py +0 -0
  282. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/add.py +0 -0
  283. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/cloud_dash.py +0 -0
  284. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/grafana/dashboards/http-overview.json +0 -0
  285. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics/__init__.py +0 -0
  286. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics/asgi.py +0 -0
  287. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics/base.py +0 -0
  288. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics/http.py +0 -0
  289. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics/sqlalchemy.py +0 -0
  290. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/metrics.py +0 -0
  291. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/__init__.py +0 -0
  292. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/compose_cloud/__init__.py +0 -0
  293. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/compose_cloud/templates/__init__.py +0 -0
  294. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
  295. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
  296. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/__init__.py +0 -0
  297. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
  298. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
  299. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
  300. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
  301. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
  302. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/dashboards/__init__.py +0 -0
  303. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/__init__.py +0 -0
  304. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
  305. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
  306. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/provisioning/__init__.py +0 -0
  307. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
  308. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
  309. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/settings.py +0 -0
  310. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
  311. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
  312. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/__init__.py +0 -0
  313. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/compose/__init__.py +0 -0
  314. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
  315. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
  316. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
  317. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
  318. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
  319. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
  320. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
  321. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
  322. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
  323. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
  324. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
  325. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
  326. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/py.typed +0 -0
  327. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/add.py +0 -0
  328. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/audit.py +0 -0
  329. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/audit_service.py +0 -0
  330. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/headers.py +0 -0
  331. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/hibp.py +0 -0
  332. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/jwt_rotation.py +0 -0
  333. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/lockout.py +0 -0
  334. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/models.py +0 -0
  335. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/org_invites.py +0 -0
  336. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/passwords.py +0 -0
  337. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/permissions.py +0 -0
  338. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/session.py +0 -0
  339. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/security/signed_cookies.py +0 -0
  340. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/utils.py +0 -0
  341. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/__init__.py +0 -0
  342. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/add.py +0 -0
  343. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/fastapi.py +0 -0
  344. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/router.py +0 -0
  345. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/service.py +0 -0
  346. {svc_infra-0.1.630 → svc_infra-0.1.631}/src/svc_infra/webhooks/signing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: svc-infra
3
- Version: 0.1.630
3
+ Version: 0.1.631
4
4
  Summary: Infrastructure for building and deploying prod-ready services
5
5
  License: MIT
6
6
  Keywords: fastapi,sqlalchemy,alembic,auth,infra,async,pydantic
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "svc-infra"
3
- version = "0.1.630"
3
+ version = "0.1.631"
4
4
  description = "Infrastructure for building and deploying prod-ready services"
5
5
  authors = ["Ali Khatami <aliikhatami94@gmail.com>"]
6
6
  license = "MIT"
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import inspect
3
4
  from datetime import datetime, timezone
4
5
  from typing import Any, Awaitable, Callable, Dict, Optional
5
6
 
@@ -123,6 +124,17 @@ def make_billing_job_handler(
123
124
  → emits topic 'billing.invoice.created'
124
125
  """
125
126
 
127
+ async def _maybe_commit(session: Any) -> None:
128
+ """Commit if the session exposes a commit method (await if coroutine).
129
+
130
+ This makes the handler resilient in tests/dev where a dummy session is used.
131
+ """
132
+ commit = getattr(session, "commit", None)
133
+ if callable(commit):
134
+ result = commit()
135
+ if inspect.isawaitable(result):
136
+ await result
137
+
126
138
  async def _handler(job: Job) -> None:
127
139
  name = job.name
128
140
  data: Dict[str, Any] = job.payload or {}
@@ -136,7 +148,7 @@ def make_billing_job_handler(
136
148
  async with session_factory() as session:
137
149
  svc = AsyncBillingService(session=session, tenant_id=tenant_id)
138
150
  total = await svc.aggregate_daily(metric=metric, day_start=day_start)
139
- await session.commit()
151
+ await _maybe_commit(session)
140
152
  webhooks.publish(
141
153
  "billing.usage_aggregated",
142
154
  {
@@ -161,7 +173,7 @@ def make_billing_job_handler(
161
173
  invoice_id = await svc.generate_monthly_invoice(
162
174
  period_start=period_start, period_end=period_end, currency=currency
163
175
  )
164
- await session.commit()
176
+ await _maybe_commit(session)
165
177
  webhooks.publish(
166
178
  "billing.invoice.created",
167
179
  {
@@ -5,6 +5,8 @@ This module offers high-level decorators for read/write caching, cache invalidat
5
5
  and resource-based cache management.
6
6
  """
7
7
 
8
+ from .add import add_cache
9
+
8
10
  # Core decorators - main public API
9
11
  from .decorators import cached # alias for cache_read
10
12
  from .decorators import mutates # alias for cache_write
@@ -32,4 +34,6 @@ __all__ = [
32
34
  # Resource-based caching
33
35
  "resource",
34
36
  "entity",
37
+ # Easy integration helper
38
+ "add_cache",
35
39
  ]
@@ -0,0 +1,158 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ Easy integration helper to wire the cache backend into an ASGI app lifecycle.
5
+
6
+ Contract:
7
+ - Idempotent: multiple calls are safe; startup/shutdown handlers are registered once.
8
+ - Env-driven defaults: respects CACHE_URL/REDIS_URL, CACHE_PREFIX, CACHE_VERSION, APP_ENV.
9
+ - Lifecycle: registers startup (init + readiness probe) and shutdown (graceful close).
10
+ - Ergonomics: exposes the underlying cache instance at app.state.cache by default.
11
+
12
+ This does not replace the per-function decorators (`cache_read`, `cache_write`) and
13
+ does not alter existing direct APIs; it simply standardizes initialization and wiring.
14
+ """
15
+
16
+ import logging
17
+ import os
18
+ from typing import Any, Callable, Optional
19
+
20
+ from svc_infra.cache.backend import DEFAULT_READINESS_TIMEOUT
21
+ from svc_infra.cache.backend import instance as _instance
22
+ from svc_infra.cache.backend import setup_cache as _setup_cache
23
+ from svc_infra.cache.backend import shutdown_cache as _shutdown_cache
24
+ from svc_infra.cache.backend import wait_ready as _wait_ready
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ def _derive_settings(
30
+ url: Optional[str], prefix: Optional[str], version: Optional[str]
31
+ ) -> tuple[str, str, str]:
32
+ """Derive cache settings from parameters or environment variables.
33
+
34
+ Precedence:
35
+ - explicit function arguments
36
+ - environment variables (CACHE_URL/REDIS_URL, CACHE_PREFIX, CACHE_VERSION)
37
+ - sensible defaults (mem://, "svc", "v1")
38
+ """
39
+
40
+ derived_url = url or os.getenv("CACHE_URL") or os.getenv("REDIS_URL") or "mem://"
41
+ derived_prefix = prefix or os.getenv("CACHE_PREFIX") or "svc"
42
+ derived_version = version or os.getenv("CACHE_VERSION") or "v1"
43
+ return derived_url, derived_prefix, derived_version
44
+
45
+
46
+ def add_cache(
47
+ app: Any | None = None,
48
+ *,
49
+ url: str | None = None,
50
+ prefix: str | None = None,
51
+ version: str | None = None,
52
+ readiness_timeout: float | None = None,
53
+ expose_state: bool = True,
54
+ state_key: str = "cache",
55
+ ) -> Callable[[], None]:
56
+ """Wire cache initialization and lifecycle into the ASGI app.
57
+
58
+ If an app is provided, registers startup/shutdown handlers. Otherwise performs
59
+ immediate initialization (best-effort) without awaiting readiness.
60
+
61
+ Returns a no-op shutdown callable for API symmetry with other helpers.
62
+ """
63
+
64
+ # Compute effective settings
65
+ eff_url, eff_prefix, eff_version = _derive_settings(url, prefix, version)
66
+
67
+ # If no app provided, do a simple init and return
68
+ if app is None:
69
+ try:
70
+ _setup_cache(url=eff_url, prefix=eff_prefix, version=eff_version)
71
+ logger.info(
72
+ "Cache initialized (no app wiring): backend=%s namespace=%s",
73
+ eff_url,
74
+ f"{eff_prefix}:{eff_version}",
75
+ )
76
+ except Exception:
77
+ logger.exception("Cache initialization failed (no app wiring)")
78
+ return lambda: None
79
+
80
+ # Idempotence: avoid duplicate wiring
81
+ try:
82
+ state = getattr(app, "state", None)
83
+ already = bool(getattr(state, "_svc_cache_wired", False))
84
+ except Exception:
85
+ state = None
86
+ already = False
87
+
88
+ if already:
89
+ logger.debug("add_cache: app already wired; skipping re-registration")
90
+ return lambda: None
91
+
92
+ # Define lifecycle handlers
93
+ async def _startup():
94
+ _setup_cache(url=eff_url, prefix=eff_prefix, version=eff_version)
95
+ try:
96
+ await _wait_ready(timeout=readiness_timeout or DEFAULT_READINESS_TIMEOUT)
97
+ except Exception:
98
+ # Bubble up to fail fast on startup; tests and prod prefer visibility
99
+ logger.exception("Cache readiness probe failed during startup")
100
+ raise
101
+ # Expose cache instance for convenience
102
+ if expose_state and hasattr(app, "state"):
103
+ try:
104
+ setattr(app.state, state_key, _instance())
105
+ except Exception:
106
+ logger.debug("Unable to expose cache instance on app.state", exc_info=True)
107
+
108
+ async def _shutdown():
109
+ try:
110
+ await _shutdown_cache()
111
+ except Exception:
112
+ # Best-effort; shutdown should not crash the app
113
+ logger.debug("Cache shutdown encountered errors (ignored)", exc_info=True)
114
+
115
+ # Register event handlers when supported
116
+ register_ok = False
117
+ try:
118
+ if hasattr(app, "add_event_handler"):
119
+ app.add_event_handler("startup", _startup)
120
+ app.add_event_handler("shutdown", _shutdown)
121
+ register_ok = True
122
+ except Exception:
123
+ register_ok = False
124
+
125
+ if not register_ok:
126
+ # Fallback: attempt FastAPI/Starlette .on_event decorators dynamically
127
+ try:
128
+ on_event = getattr(app, "on_event", None)
129
+ if callable(on_event):
130
+ on_event("startup")(_startup) # type: ignore[misc]
131
+ on_event("shutdown")(_shutdown) # type: ignore[misc]
132
+ register_ok = True
133
+ except Exception:
134
+ register_ok = False
135
+
136
+ # Mark wired and expose state immediately if desired
137
+ if hasattr(app, "state"):
138
+ try:
139
+ setattr(app.state, "_svc_cache_wired", True)
140
+ if expose_state and not hasattr(app.state, state_key):
141
+ setattr(app.state, state_key, _instance())
142
+ except Exception:
143
+ pass
144
+
145
+ if register_ok:
146
+ logger.info("Cache wired: url=%s namespace=%s", eff_url, f"{eff_prefix}:{eff_version}")
147
+ else:
148
+ # If we cannot register handlers, at least initialize now
149
+ try:
150
+ _setup_cache(url=eff_url, prefix=eff_prefix, version=eff_version)
151
+ except Exception:
152
+ logger.exception("Cache initialization failed (no event registration)")
153
+
154
+ # Return a simple shutdown handle for symmetry with other add_* helpers
155
+ return lambda: None
156
+
157
+
158
+ __all__ = ["add_cache"]
@@ -0,0 +1,76 @@
1
+ # Cache guide
2
+
3
+ The cache module wraps [cashews](https://github.com/Krukov/cashews) with decorators and namespace helpers so services can centralize key formats.
4
+
5
+ ```python
6
+ from svc_infra.cache import cache_read, cache_write, init_cache
7
+
8
+ init_cache() # uses CACHE_PREFIX / CACHE_VERSION
9
+
10
+ @cache_read(key="user:{user_id}", ttl=300)
11
+ async def get_user(user_id: int):
12
+ ...
13
+ ```
14
+
15
+ ### Environment
16
+
17
+ - `CACHE_PREFIX`, `CACHE_VERSION` – change the namespace alias used by the decorators. 【F:src/svc_infra/cache/README.md†L20-L173】
18
+ - `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG` – override canonical TTL buckets. 【F:src/svc_infra/cache/ttl.py†L26-L55】
19
+
20
+ ## Easy integration: add_cache
21
+
22
+ Use the one-liner helper to wire cache initialization into your ASGI app lifecycle with sensible defaults. This doesn’t replace the decorators; it standardizes init/readiness/shutdown and exposes a handle for convenience.
23
+
24
+ ```python
25
+ from fastapi import FastAPI
26
+ from svc_infra.cache import add_cache, cache_read, cache_write, resource
27
+
28
+ app = FastAPI()
29
+
30
+ # Wires startup (init + readiness) and shutdown (graceful close). Idempotent.
31
+ add_cache(app)
32
+
33
+ user = resource("user", "user_id")
34
+
35
+ @user.cache_read(suffix="profile", ttl=300)
36
+ async def get_user_profile(user_id: int):
37
+ ...
38
+
39
+ @user.cache_write()
40
+ async def update_user_profile(user_id: int, payload):
41
+ ...
42
+
43
+ # Optional: direct cache instance for advanced scenarios
44
+ # available after startup when using add_cache(app)
45
+ # app.state.cache -> cashews cache instance
46
+ ```
47
+
48
+ ### Env-driven defaults
49
+
50
+ - URL: `CACHE_URL` → `REDIS_URL` → `mem://`
51
+ - Prefix: `CACHE_PREFIX` (default `svc`)
52
+ - Version: `CACHE_VERSION` (default `v1`)
53
+
54
+ You can override explicitly:
55
+
56
+ ```python
57
+ add_cache(app, url="redis://localhost:6379/0", prefix="myapp", version="v2")
58
+ ```
59
+
60
+ ### Behavior
61
+
62
+ - Idempotent: multiple calls won’t duplicate handlers.
63
+ - Startup/shutdown hooks: registered when supported by the app; startup performs a readiness probe. Startup is optional for correctness, but recommended for production reliability.
64
+ - app.state exposure: by default, exposes `app.state.cache` to access the underlying cashews instance.
65
+
66
+ ### No-app usage
67
+
68
+ If you’re not wiring an app (e.g., a script), you can initialize without startup hooks:
69
+
70
+ ```python
71
+ from svc_infra.cache import add_cache
72
+
73
+ shutdown = add_cache(None) # immediate init (best-effort)
74
+ # ... do work ...
75
+ # call shutdown() is a no-op placeholder for symmetry
76
+ ```
@@ -1,18 +0,0 @@
1
- # Cache guide
2
-
3
- The cache module wraps [cashews](https://github.com/Krukov/cashews) with decorators and namespace helpers so services can centralize key formats.
4
-
5
- ```python
6
- from svc_infra.cache import cache_read, cache_write, init_cache
7
-
8
- init_cache() # uses CACHE_PREFIX / CACHE_VERSION
9
-
10
- @cache_read(key="user:{user_id}", ttl=300)
11
- async def get_user(user_id: int):
12
- ...
13
- ```
14
-
15
- ### Environment
16
-
17
- - `CACHE_PREFIX`, `CACHE_VERSION` – change the namespace alias used by the decorators. 【F:src/svc_infra/cache/README.md†L20-L173】
18
- - `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG` – override canonical TTL buckets. 【F:src/svc_infra/cache/ttl.py†L26-L55】
File without changes