svc-infra 0.1.631__tar.gz → 0.1.709__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 (408) hide show
  1. svc_infra-0.1.709/LICENSE +21 -0
  2. svc_infra-0.1.709/PKG-INFO +356 -0
  3. svc_infra-0.1.709/README.md +271 -0
  4. svc_infra-0.1.709/pyproject.toml +165 -0
  5. svc_infra-0.1.709/src/svc_infra/__init__.py +59 -0
  6. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/models.py +133 -42
  7. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/provider/aiydan.py +121 -47
  8. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/provider/base.py +30 -9
  9. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/provider/stripe.py +156 -62
  10. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/schemas.py +18 -9
  11. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/service.py +98 -41
  12. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/settings.py +5 -1
  13. svc_infra-0.1.709/src/svc_infra/api/__init__.py +61 -0
  14. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/__init__.py +15 -0
  15. svc_infra-0.1.709/src/svc_infra/api/fastapi/admin/__init__.py +3 -0
  16. svc_infra-0.1.709/src/svc_infra/api/fastapi/admin/add.py +245 -0
  17. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/apf_payments/router.py +78 -30
  18. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/apf_payments/setup.py +13 -6
  19. svc_infra-0.1.709/src/svc_infra/api/fastapi/auth/__init__.py +65 -0
  20. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/_cookies.py +6 -2
  21. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/add.py +17 -14
  22. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/gaurd.py +43 -14
  23. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/models.py +3 -1
  24. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +10 -6
  25. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/router.py +15 -8
  26. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/security.py +1 -2
  27. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/utils.py +2 -1
  28. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/mfa/verify.py +9 -2
  29. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/policy.py +0 -1
  30. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/providers.py +3 -1
  31. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +6 -6
  32. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +144 -45
  33. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/routers/session_router.py +6 -2
  34. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/security.py +31 -10
  35. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/sender.py +8 -1
  36. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/state.py +3 -1
  37. svc_infra-0.1.709/src/svc_infra/api/fastapi/auth/ws_security.py +275 -0
  38. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/billing/router.py +13 -4
  39. svc_infra-0.1.709/src/svc_infra/api/fastapi/cache/add.py +18 -0
  40. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/__init__.py +5 -1
  41. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/http.py +3 -1
  42. svc_infra-0.1.709/src/svc_infra/api/fastapi/db/nosql/__init__.py +46 -0
  43. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +47 -32
  44. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +30 -11
  45. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/__init__.py +5 -1
  46. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/add.py +39 -13
  47. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/crud_router.py +74 -48
  48. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/health.py +3 -1
  49. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/session.py +3 -1
  50. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/users.py +18 -6
  51. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +25 -11
  52. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/docs/add.py +21 -8
  53. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/docs/landing.py +4 -2
  54. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/docs/scoped.py +62 -15
  55. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dual/__init__.py +12 -2
  56. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dual/dualize.py +1 -1
  57. svc_infra-0.1.709/src/svc_infra/api/fastapi/dual/protected.py +218 -0
  58. svc_infra-0.1.709/src/svc_infra/api/fastapi/dual/public.py +47 -0
  59. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dual/router.py +40 -13
  60. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dx.py +33 -2
  61. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/ease.py +10 -2
  62. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/http/concurrency.py +2 -1
  63. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/http/conditional.py +3 -1
  64. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/debug.py +4 -1
  65. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +6 -2
  66. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +1 -1
  67. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +13 -5
  68. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/graceful_shutdown.py +22 -5
  69. svc_infra-0.1.709/src/svc_infra/api/fastapi/middleware/idempotency.py +213 -0
  70. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +8 -3
  71. svc_infra-0.1.709/src/svc_infra/api/fastapi/middleware/ratelimit.py +158 -0
  72. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +31 -4
  73. svc_infra-0.1.709/src/svc_infra/api/fastapi/middleware/request_id.py +39 -0
  74. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +3 -3
  75. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/timeout.py +65 -32
  76. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/apply.py +5 -3
  77. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/conventions.py +9 -2
  78. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/mutators.py +53 -22
  79. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/pipeline.py +1 -1
  80. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/security.py +3 -1
  81. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/ops/add.py +3 -1
  82. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/pagination.py +44 -19
  83. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/routers/__init__.py +43 -15
  84. svc_infra-0.1.709/src/svc_infra/api/fastapi/setup.py +407 -0
  85. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/tenancy/context.py +3 -3
  86. svc_infra-0.1.709/src/svc_infra/api/fastapi/versioned.py +101 -0
  87. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/__init__.py +3 -1
  88. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/env.py +69 -1
  89. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/logging/add.py +9 -2
  90. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/logging/formats.py +12 -5
  91. svc_infra-0.1.709/src/svc_infra/billing/__init__.py +46 -0
  92. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/async_service.py +24 -1
  93. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/jobs.py +15 -4
  94. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/models.py +69 -23
  95. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/quotas.py +3 -1
  96. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/schemas.py +7 -4
  97. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/billing/service.py +44 -2
  98. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/__init__.py +5 -0
  99. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/add.py +21 -9
  100. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/backend.py +2 -4
  101. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/decorators.py +81 -33
  102. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/demo.py +2 -2
  103. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/recache.py +26 -14
  104. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/resources.py +14 -5
  105. svc_infra-0.1.709/src/svc_infra/cache/tags.py +52 -0
  106. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/utils.py +3 -1
  107. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/__init__.py +22 -2
  108. svc_infra-0.1.709/src/svc_infra/cli/cmds/__init__.py +55 -0
  109. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +3 -1
  110. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +3 -1
  111. svc_infra-0.1.709/src/svc_infra/cli/cmds/db/ops_cmds.py +270 -0
  112. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +24 -8
  113. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +18 -10
  114. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/docs/docs_cmds.py +3 -1
  115. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/dx/dx_cmds.py +22 -5
  116. svc_infra-0.1.709/src/svc_infra/cli/cmds/health/__init__.py +179 -0
  117. svc_infra-0.1.709/src/svc_infra/cli/cmds/health/health_cmds.py +8 -0
  118. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +6 -2
  119. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/obs/obs_cmds.py +32 -12
  120. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/sdk/sdk_cmds.py +15 -5
  121. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/foundation/runner.py +6 -2
  122. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/data/add.py +2 -2
  123. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/data/backup.py +7 -2
  124. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/data/erasure.py +1 -1
  125. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/data/fixtures.py +5 -3
  126. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/data/retention.py +11 -5
  127. svc_infra-0.1.709/src/svc_infra/db/__init__.py +15 -0
  128. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/crud_schema.py +9 -9
  129. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/__init__.py +3 -0
  130. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/core.py +30 -9
  131. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/indexes.py +3 -1
  132. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/management.py +1 -1
  133. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/client.py +19 -2
  134. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/settings.py +6 -2
  135. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/repository.py +35 -15
  136. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/resource.py +20 -3
  137. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/scaffold.py +9 -3
  138. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/service.py +3 -1
  139. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/types.py +6 -2
  140. svc_infra-0.1.709/src/svc_infra/db/ops.py +384 -0
  141. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/outbox.py +6 -2
  142. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/apikey.py +37 -9
  143. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/authref.py +9 -3
  144. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/constants.py +12 -8
  145. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/core.py +2 -2
  146. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/management.py +11 -8
  147. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/repository.py +52 -17
  148. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/scaffold.py +6 -2
  149. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/service.py +15 -5
  150. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +7 -56
  151. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +25 -11
  152. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +20 -5
  153. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/tenant.py +13 -4
  154. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/uniq_hooks.py +9 -3
  155. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/utils.py +138 -51
  156. svc_infra-0.1.709/src/svc_infra/deploy/__init__.py +538 -0
  157. svc_infra-0.1.709/src/svc_infra/documents/__init__.py +100 -0
  158. svc_infra-0.1.709/src/svc_infra/documents/add.py +264 -0
  159. svc_infra-0.1.709/src/svc_infra/documents/ease.py +233 -0
  160. svc_infra-0.1.709/src/svc_infra/documents/models.py +114 -0
  161. svc_infra-0.1.709/src/svc_infra/documents/storage.py +264 -0
  162. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/dx/add.py +3 -1
  163. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/dx/checks.py +3 -2
  164. svc_infra-0.1.709/src/svc_infra/exceptions.py +141 -0
  165. svc_infra-0.1.709/src/svc_infra/health/__init__.py +864 -0
  166. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/http/client.py +43 -2
  167. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/builtins/outbox_processor.py +3 -1
  168. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/builtins/webhook_delivery.py +7 -2
  169. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/easy.py +1 -0
  170. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/loader.py +10 -5
  171. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/queue.py +39 -4
  172. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/redis_queue.py +87 -22
  173. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/runner.py +6 -2
  174. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/scheduler.py +13 -1
  175. svc_infra-0.1.709/src/svc_infra/loaders/__init__.py +186 -0
  176. svc_infra-0.1.709/src/svc_infra/loaders/base.py +142 -0
  177. svc_infra-0.1.709/src/svc_infra/loaders/github.py +311 -0
  178. svc_infra-0.1.709/src/svc_infra/loaders/models.py +147 -0
  179. svc_infra-0.1.709/src/svc_infra/loaders/url.py +235 -0
  180. svc_infra-0.1.709/src/svc_infra/logging/__init__.py +374 -0
  181. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/mcp/svc_infra_mcp.py +5 -4
  182. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/add.py +13 -4
  183. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/cloud_dash.py +2 -1
  184. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics/__init__.py +3 -4
  185. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics/asgi.py +13 -7
  186. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics/http.py +9 -5
  187. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics/sqlalchemy.py +13 -9
  188. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics.py +6 -5
  189. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/settings.py +6 -2
  190. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/add.py +23 -7
  191. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/audit.py +92 -10
  192. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/audit_service.py +4 -3
  193. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/headers.py +15 -2
  194. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/hibp.py +8 -2
  195. svc_infra-0.1.709/src/svc_infra/security/jwt_rotation.py +105 -0
  196. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/lockout.py +11 -5
  197. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/models.py +54 -12
  198. svc_infra-0.1.709/src/svc_infra/security/oauth_models.py +73 -0
  199. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/org_invites.py +5 -3
  200. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/passwords.py +3 -1
  201. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/permissions.py +25 -2
  202. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/session.py +1 -1
  203. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/security/signed_cookies.py +21 -1
  204. svc_infra-0.1.709/src/svc_infra/storage/__init__.py +93 -0
  205. svc_infra-0.1.709/src/svc_infra/storage/add.py +253 -0
  206. svc_infra-0.1.709/src/svc_infra/storage/backends/__init__.py +11 -0
  207. svc_infra-0.1.709/src/svc_infra/storage/backends/local.py +339 -0
  208. svc_infra-0.1.709/src/svc_infra/storage/backends/memory.py +216 -0
  209. svc_infra-0.1.709/src/svc_infra/storage/backends/s3.py +353 -0
  210. svc_infra-0.1.709/src/svc_infra/storage/base.py +239 -0
  211. svc_infra-0.1.709/src/svc_infra/storage/easy.py +185 -0
  212. svc_infra-0.1.709/src/svc_infra/storage/settings.py +195 -0
  213. svc_infra-0.1.709/src/svc_infra/testing/__init__.py +685 -0
  214. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/utils.py +7 -3
  215. svc_infra-0.1.709/src/svc_infra/webhooks/__init__.py +69 -0
  216. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/webhooks/add.py +65 -48
  217. svc_infra-0.1.709/src/svc_infra/webhooks/encryption.py +115 -0
  218. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/webhooks/fastapi.py +3 -1
  219. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/webhooks/service.py +4 -1
  220. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/webhooks/signing.py +5 -1
  221. svc_infra-0.1.709/src/svc_infra/websocket/__init__.py +79 -0
  222. svc_infra-0.1.709/src/svc_infra/websocket/add.py +140 -0
  223. svc_infra-0.1.709/src/svc_infra/websocket/client.py +282 -0
  224. svc_infra-0.1.709/src/svc_infra/websocket/config.py +69 -0
  225. svc_infra-0.1.709/src/svc_infra/websocket/easy.py +76 -0
  226. svc_infra-0.1.709/src/svc_infra/websocket/exceptions.py +61 -0
  227. svc_infra-0.1.709/src/svc_infra/websocket/manager.py +344 -0
  228. svc_infra-0.1.709/src/svc_infra/websocket/models.py +49 -0
  229. svc_infra-0.1.631/PKG-INFO +0 -140
  230. svc_infra-0.1.631/README.md +0 -63
  231. svc_infra-0.1.631/pyproject.toml +0 -143
  232. svc_infra-0.1.631/src/svc_infra/__init__.py +0 -3
  233. svc_infra-0.1.631/src/svc_infra/api/fastapi/cache/add.py +0 -14
  234. svc_infra-0.1.631/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -8
  235. svc_infra-0.1.631/src/svc_infra/api/fastapi/dual/protected.py +0 -96
  236. svc_infra-0.1.631/src/svc_infra/api/fastapi/dual/public.py +0 -22
  237. svc_infra-0.1.631/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -116
  238. svc_infra-0.1.631/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -119
  239. svc_infra-0.1.631/src/svc_infra/api/fastapi/middleware/request_id.py +0 -23
  240. svc_infra-0.1.631/src/svc_infra/api/fastapi/setup.py +0 -286
  241. svc_infra-0.1.631/src/svc_infra/billing/__init__.py +0 -23
  242. svc_infra-0.1.631/src/svc_infra/cache/tags.py +0 -77
  243. svc_infra-0.1.631/src/svc_infra/cli/cmds/__init__.py +0 -28
  244. svc_infra-0.1.631/src/svc_infra/docs/acceptance-matrix.md +0 -71
  245. svc_infra-0.1.631/src/svc_infra/docs/acceptance.md +0 -44
  246. svc_infra-0.1.631/src/svc_infra/docs/adr/0002-background-jobs-and-scheduling.md +0 -40
  247. svc_infra-0.1.631/src/svc_infra/docs/adr/0003-webhooks-framework.md +0 -24
  248. svc_infra-0.1.631/src/svc_infra/docs/adr/0004-tenancy-model.md +0 -42
  249. svc_infra-0.1.631/src/svc_infra/docs/adr/0005-data-lifecycle.md +0 -86
  250. svc_infra-0.1.631/src/svc_infra/docs/adr/0006-ops-slos-and-metrics.md +0 -47
  251. svc_infra-0.1.631/src/svc_infra/docs/adr/0007-docs-and-sdks.md +0 -83
  252. svc_infra-0.1.631/src/svc_infra/docs/adr/0008-billing-primitives.md +0 -143
  253. svc_infra-0.1.631/src/svc_infra/docs/adr/0009-acceptance-harness.md +0 -40
  254. svc_infra-0.1.631/src/svc_infra/docs/adr/0010-timeouts-and-resource-limits.md +0 -54
  255. svc_infra-0.1.631/src/svc_infra/docs/api.md +0 -59
  256. svc_infra-0.1.631/src/svc_infra/docs/auth.md +0 -11
  257. svc_infra-0.1.631/src/svc_infra/docs/billing.md +0 -190
  258. svc_infra-0.1.631/src/svc_infra/docs/cache.md +0 -76
  259. svc_infra-0.1.631/src/svc_infra/docs/cli.md +0 -74
  260. svc_infra-0.1.631/src/svc_infra/docs/contributing.md +0 -34
  261. svc_infra-0.1.631/src/svc_infra/docs/data-lifecycle.md +0 -52
  262. svc_infra-0.1.631/src/svc_infra/docs/database.md +0 -14
  263. svc_infra-0.1.631/src/svc_infra/docs/docs-and-sdks.md +0 -62
  264. svc_infra-0.1.631/src/svc_infra/docs/environment.md +0 -114
  265. svc_infra-0.1.631/src/svc_infra/docs/getting-started.md +0 -63
  266. svc_infra-0.1.631/src/svc_infra/docs/idempotency.md +0 -111
  267. svc_infra-0.1.631/src/svc_infra/docs/jobs.md +0 -67
  268. svc_infra-0.1.631/src/svc_infra/docs/observability.md +0 -16
  269. svc_infra-0.1.631/src/svc_infra/docs/ops.md +0 -37
  270. svc_infra-0.1.631/src/svc_infra/docs/rate-limiting.md +0 -125
  271. svc_infra-0.1.631/src/svc_infra/docs/repo-review.md +0 -48
  272. svc_infra-0.1.631/src/svc_infra/docs/security.md +0 -155
  273. svc_infra-0.1.631/src/svc_infra/docs/tenancy.md +0 -35
  274. svc_infra-0.1.631/src/svc_infra/docs/timeouts-and-resource-limits.md +0 -147
  275. svc_infra-0.1.631/src/svc_infra/docs/webhooks.md +0 -112
  276. svc_infra-0.1.631/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
  277. svc_infra-0.1.631/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
  278. svc_infra-0.1.631/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
  279. svc_infra-0.1.631/src/svc_infra/security/jwt_rotation.py +0 -53
  280. svc_infra-0.1.631/src/svc_infra/webhooks/__init__.py +0 -16
  281. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/README.md +0 -0
  282. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/__init__.py +0 -0
  283. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/alembic.py +0 -0
  284. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/provider/__init__.py +0 -0
  285. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/apf_payments/provider/registry.py +0 -0
  286. {svc_infra-0.1.631/src/svc_infra/api → svc_infra-0.1.709/src/svc_infra/api/fastapi/apf_payments}/__init__.py +0 -0
  287. {svc_infra-0.1.631/src/svc_infra/api/fastapi/apf_payments → svc_infra-0.1.709/src/svc_infra/api/fastapi/auth/mfa}/__init__.py +0 -0
  288. {svc_infra-0.1.631/src/svc_infra/api/fastapi/auth → svc_infra-0.1.709/src/svc_infra/api/fastapi/auth/routers}/__init__.py +0 -0
  289. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
  290. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/auth/settings.py +0 -0
  291. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/billing/setup.py +0 -0
  292. {svc_infra-0.1.631/src/svc_infra/api/fastapi/auth/mfa → svc_infra-0.1.709/src/svc_infra/api/fastapi/cache}/__init__.py +0 -0
  293. {svc_infra-0.1.631/src/svc_infra/api/fastapi/auth/routers → svc_infra-0.1.709/src/svc_infra/api/fastapi/db/nosql/mongo}/__init__.py +0 -0
  294. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
  295. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/db/sql/README.md +0 -0
  296. {svc_infra-0.1.631/src/svc_infra/api/fastapi/cache → svc_infra-0.1.709/src/svc_infra/api/fastapi/docs}/__init__.py +0 -0
  297. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
  298. {svc_infra-0.1.631/src/svc_infra/api/fastapi/db/nosql/mongo → svc_infra-0.1.709/src/svc_infra/api/fastapi/http}/__init__.py +0 -0
  299. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
  300. {svc_infra-0.1.631/src/svc_infra/api/fastapi/docs → svc_infra-0.1.709/src/svc_infra/api/fastapi/middleware}/__init__.py +0 -0
  301. {svc_infra-0.1.631/src/svc_infra/api/fastapi/http → svc_infra-0.1.709/src/svc_infra/api/fastapi/middleware/errors}/__init__.py +0 -0
  302. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +0 -0
  303. {svc_infra-0.1.631/src/svc_infra/api/fastapi/middleware → svc_infra-0.1.709/src/svc_infra/api/fastapi/openapi}/__init__.py +0 -0
  304. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/models.py +0 -0
  305. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/openapi/responses.py +0 -0
  306. {svc_infra-0.1.631/src/svc_infra/api/fastapi/middleware/errors → svc_infra-0.1.709/src/svc_infra/api/fastapi/paths}/__init__.py +0 -0
  307. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
  308. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
  309. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
  310. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/paths/user.py +0 -0
  311. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
  312. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/api/fastapi/tenancy/add.py +0 -0
  313. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/README.md +0 -0
  314. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/logging/__init__.py +0 -0
  315. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/logging/filter.py +0 -0
  316. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/app/root.py +0 -0
  317. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/bundled_docs/README.md +0 -0
  318. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/bundled_docs/__init__.py +0 -0
  319. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/bundled_docs/getting-started.md +0 -0
  320. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/README.md +0 -0
  321. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/keys.py +0 -0
  322. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cache/ttl.py +0 -0
  323. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/__main__.py +0 -0
  324. {svc_infra-0.1.631/src/svc_infra/api/fastapi/openapi → svc_infra-0.1.709/src/svc_infra/cli/cmds/db}/__init__.py +0 -0
  325. {svc_infra-0.1.631/src/svc_infra/api/fastapi/paths → svc_infra-0.1.709/src/svc_infra/cli/cmds/db/nosql}/__init__.py +0 -0
  326. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +0 -0
  327. {svc_infra-0.1.631/src/svc_infra/cli/cmds/db → svc_infra-0.1.709/src/svc_infra/cli/cmds/db/nosql/mongo}/__init__.py +0 -0
  328. {svc_infra-0.1.631/src/svc_infra/cli/cmds/db/nosql → svc_infra-0.1.709/src/svc_infra/cli/cmds/db/sql}/__init__.py +0 -0
  329. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +0 -0
  330. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/dx/__init__.py +0 -0
  331. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/help.py +0 -0
  332. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
  333. {svc_infra-0.1.631/src/svc_infra/cli/cmds/db/nosql/mongo → svc_infra-0.1.709/src/svc_infra/cli/cmds/obs}/__init__.py +0 -0
  334. {svc_infra-0.1.631/src/svc_infra/cli/cmds/db/sql → svc_infra-0.1.709/src/svc_infra/cli/cmds/sdk}/__init__.py +0 -0
  335. {svc_infra-0.1.631/src/svc_infra/cli/cmds/obs → svc_infra-0.1.709/src/svc_infra/cli/foundation}/__init__.py +0 -0
  336. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/cli/foundation/typer_bootstrap.py +0 -0
  337. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/inbox.py +0 -0
  338. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/base.py +0 -0
  339. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/constants.py +0 -0
  340. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/README.md +0 -0
  341. {svc_infra-0.1.631/src/svc_infra/cli/cmds/sdk → svc_infra-0.1.709/src/svc_infra/db/nosql/mongo}/__init__.py +0 -0
  342. {svc_infra-0.1.631/src/svc_infra/cli/foundation → svc_infra-0.1.709/src/svc_infra/db/nosql/mongo/templates}/__init__.py +0 -0
  343. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
  344. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
  345. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
  346. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/service_with_hooks.py +0 -0
  347. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/nosql/utils.py +0 -0
  348. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/README.md +0 -0
  349. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/__init__.py +0 -0
  350. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/base.py +0 -0
  351. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/resource.py +0 -0
  352. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/service_with_hooks.py +0 -0
  353. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/__init__.py +0 -0
  354. {svc_infra-0.1.631/src/svc_infra/db → svc_infra-0.1.709/src/svc_infra/db/sql/templates/models_schemas}/__init__.py +0 -0
  355. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
  356. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
  357. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
  358. {svc_infra-0.1.631/src/svc_infra/db/nosql/mongo → svc_infra-0.1.709/src/svc_infra/db/sql/templates/setup}/__init__.py +0 -0
  359. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
  360. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
  361. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/types.py +0 -0
  362. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/uniq.py +0 -0
  363. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/sql/versioning.py +0 -0
  364. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/db/utils.py +0 -0
  365. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/dx/changelog.py +0 -0
  366. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/http/__init__.py +0 -0
  367. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/jobs/worker.py +0 -0
  368. {svc_infra-0.1.631/src/svc_infra/db/nosql/mongo/templates → svc_infra-0.1.709/src/svc_infra/mcp}/__init__.py +0 -0
  369. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/README.md +0 -0
  370. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/__init__.py +0 -0
  371. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/grafana/dashboards/http-overview.json +0 -0
  372. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/metrics/base.py +0 -0
  373. {svc_infra-0.1.631/src/svc_infra/db/sql/templates/models_schemas → svc_infra-0.1.709/src/svc_infra/obs/providers}/__init__.py +0 -0
  374. {svc_infra-0.1.631/src/svc_infra/db/sql/templates/setup → svc_infra-0.1.709/src/svc_infra/obs/providers/compose_cloud}/__init__.py +0 -0
  375. {svc_infra-0.1.631/src/svc_infra/mcp → svc_infra-0.1.709/src/svc_infra/obs/providers/compose_cloud/templates}/__init__.py +0 -0
  376. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
  377. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
  378. {svc_infra-0.1.631/src/svc_infra/obs/providers → svc_infra-0.1.709/src/svc_infra/obs/providers/grafana}/__init__.py +0 -0
  379. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
  380. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
  381. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
  382. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
  383. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
  384. {svc_infra-0.1.631/src/svc_infra/obs/providers/compose_cloud → svc_infra-0.1.709/src/svc_infra/obs/providers/grafana/dashboards}/__init__.py +0 -0
  385. {svc_infra-0.1.631/src/svc_infra/obs/providers/compose_cloud → svc_infra-0.1.709/src/svc_infra/obs/providers/grafana}/templates/__init__.py +0 -0
  386. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
  387. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
  388. {svc_infra-0.1.631/src/svc_infra/obs/providers/grafana → svc_infra-0.1.709/src/svc_infra/obs/providers/grafana/templates/provisioning}/__init__.py +0 -0
  389. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
  390. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
  391. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
  392. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
  393. {svc_infra-0.1.631/src/svc_infra/obs/providers/grafana/dashboards → svc_infra-0.1.709/src/svc_infra/obs/templates/sidecars}/__init__.py +0 -0
  394. {svc_infra-0.1.631/src/svc_infra/obs/providers/grafana/templates → svc_infra-0.1.709/src/svc_infra/obs/templates/sidecars/compose}/__init__.py +0 -0
  395. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
  396. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
  397. {svc_infra-0.1.631/src/svc_infra/obs/providers/grafana/templates/provisioning → svc_infra-0.1.709/src/svc_infra/obs/templates/sidecars/fly}/__init__.py +0 -0
  398. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
  399. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
  400. {svc_infra-0.1.631/src/svc_infra/obs/templates/sidecars → svc_infra-0.1.709/src/svc_infra/obs/templates/sidecars/k8s}/__init__.py +0 -0
  401. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
  402. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
  403. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
  404. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
  405. {svc_infra-0.1.631/src/svc_infra/obs/templates/sidecars/compose → svc_infra-0.1.709/src/svc_infra/obs/templates/sidecars/railway}/__init__.py +0 -0
  406. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
  407. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/py.typed +0 -0
  408. {svc_infra-0.1.631 → svc_infra-0.1.709}/src/svc_infra/webhooks/router.py +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 nfrax
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,356 @@
1
+ Metadata-Version: 2.3
2
+ Name: svc-infra
3
+ Version: 0.1.709
4
+ Summary: Infrastructure for building and deploying prod-ready services
5
+ License: MIT
6
+ Keywords: fastapi,sqlalchemy,alembic,auth,infra,async,pydantic
7
+ Author: Ali Khatami
8
+ Author-email: aliikhatami94@gmail.com
9
+ Requires-Python: >=3.11,<4.0
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Framework :: FastAPI
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Provides-Extra: adyen
23
+ Provides-Extra: duckdb
24
+ Provides-Extra: metrics
25
+ Provides-Extra: mongodb
26
+ Provides-Extra: mssql
27
+ Provides-Extra: mysql
28
+ Provides-Extra: payments
29
+ Provides-Extra: pg
30
+ Provides-Extra: pg2
31
+ Provides-Extra: redshift
32
+ Provides-Extra: s3
33
+ Provides-Extra: snowflake
34
+ Provides-Extra: sqlite
35
+ Provides-Extra: stripe
36
+ Requires-Dist: adyen (>=10.0.0) ; extra == "payments" or extra == "adyen"
37
+ Requires-Dist: aioboto3 (>=12.0.0) ; extra == "s3"
38
+ Requires-Dist: aiofiles (>=24.0.0)
39
+ Requires-Dist: aiosqlite (>=0.19.0) ; extra == "sqlite"
40
+ Requires-Dist: alembic (>=1.13.0)
41
+ Requires-Dist: asyncpg (>=0.29.0) ; extra == "pg"
42
+ Requires-Dist: authlib (>=1.0.0)
43
+ Requires-Dist: cashews[redis] (>=7.0)
44
+ Requires-Dist: duckdb (>=0.10.0) ; extra == "duckdb"
45
+ Requires-Dist: email-validator (>=2.0.0)
46
+ Requires-Dist: fastapi (>=0.110.0)
47
+ Requires-Dist: fastapi-users-db-sqlalchemy (>=7.0.0)
48
+ Requires-Dist: fastapi-users[oauth] (>=14.0.0)
49
+ Requires-Dist: greenlet (>=3.0)
50
+ Requires-Dist: httpx (>=0.25.0)
51
+ Requires-Dist: httpx-oauth (>=0.15.0)
52
+ Requires-Dist: itsdangerous (>=2.0.0)
53
+ Requires-Dist: mcp (>=1.0.0)
54
+ Requires-Dist: motor (>=3.0.0) ; extra == "mongodb"
55
+ Requires-Dist: mysqlclient (>=2.2.0) ; extra == "mysql"
56
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.20.0)
57
+ Requires-Dist: opentelemetry-instrumentation-fastapi (>=0.41b0)
58
+ Requires-Dist: opentelemetry-instrumentation-httpx (>=0.41b0)
59
+ Requires-Dist: opentelemetry-instrumentation-requests (>=0.41b0)
60
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.41b0)
61
+ Requires-Dist: opentelemetry-propagator-b3 (>=1.20.0)
62
+ Requires-Dist: opentelemetry-sdk (>=1.20.0)
63
+ Requires-Dist: passlib[bcrypt] (>=1.7.4)
64
+ Requires-Dist: prometheus-client (>=0.18.0) ; extra == "metrics"
65
+ Requires-Dist: psycopg2-binary (>=2.9.0) ; extra == "pg2"
66
+ Requires-Dist: psycopg[binary] (>=3.0) ; extra == "pg"
67
+ Requires-Dist: pydantic-settings (>=2.0)
68
+ Requires-Dist: pymysql (>=1.1.0) ; extra == "mysql"
69
+ Requires-Dist: pyodbc (>=5.0.0) ; extra == "mssql"
70
+ Requires-Dist: pyotp (>=2.9.0)
71
+ Requires-Dist: python-dotenv (>=1.0.0)
72
+ Requires-Dist: redis (>=5.0.0)
73
+ Requires-Dist: redshift-connector (>=2.0.0) ; extra == "redshift"
74
+ Requires-Dist: snowflake-connector-python (>=3.0.0) ; extra == "snowflake"
75
+ Requires-Dist: sqlalchemy[asyncio] (>=2.0)
76
+ Requires-Dist: stripe (>=7.0.0) ; extra == "payments" or extra == "stripe"
77
+ Requires-Dist: typer (>=0.12.0)
78
+ Requires-Dist: websockets (>=12.0)
79
+ Project-URL: Documentation, https://nfrax.com/svc-infra
80
+ Project-URL: Homepage, https://github.com/nfraxlab/svc-infra
81
+ Project-URL: Issues, https://github.com/nfraxlab/svc-infra/issues
82
+ Project-URL: Repository, https://github.com/nfraxlab/svc-infra
83
+ Description-Content-Type: text/markdown
84
+
85
+ <div align="center">
86
+
87
+ # svc-infra
88
+
89
+ ### Production-ready FastAPI infrastructure in one import
90
+
91
+ [![PyPI](https://img.shields.io/pypi/v/svc-infra.svg)](https://pypi.org/project/svc-infra/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://static.pepy.tech/badge/svc-infra/month)](https://pepy.tech/project/svc-infra)
92
+
93
+ **Stop rebuilding auth, billing, webhooks, and background jobs for every project.**
94
+
95
+ [Documentation](docs/) · [Examples](examples/) · [PyPI](https://pypi.org/project/svc-infra/)
96
+
97
+ </div>
98
+
99
+ ---
100
+
101
+ ## Why svc-infra?
102
+
103
+ Every FastAPI project needs the same things: authentication, database setup, background jobs, caching, webhooks, billing... You've written this code before. Multiple times.
104
+
105
+ **svc-infra** packages battle-tested infrastructure used in production, so you can focus on your actual product:
106
+
107
+ ```python
108
+ from svc_infra.api.fastapi.ease import easy_service_app
109
+
110
+ app = easy_service_app(name="MyAPI", release="1.0.0")
111
+ # ✅ Health checks, CORS, security headers, structured logging
112
+ # ✅ Prometheus metrics, OpenTelemetry tracing
113
+ # ✅ Request IDs, idempotency middleware
114
+ # That's it. Ship it.
115
+ ```
116
+
117
+ ## ⚡ Quick Install
118
+
119
+ ```bash
120
+ pip install svc-infra
121
+ ```
122
+
123
+ ## 🎯 What's Included
124
+
125
+ | Feature | What You Get | One-liner |
126
+ |---------|-------------|-----------|
127
+ | **🔐 Auth** | JWT, sessions, OAuth/OIDC, MFA, API keys | `add_auth_users(app)` |
128
+ | **💳 Billing** | Usage tracking, subscriptions, invoices, Stripe sync | `add_billing(app)` |
129
+ | **📦 Database** | PostgreSQL + MongoDB, migrations, inbox/outbox | `add_sql_db(app)` |
130
+ | **⚡ Jobs** | Background tasks, scheduling, retries, DLQ | `easy_jobs()` |
131
+ | **🔗 Webhooks** | Subscriptions, HMAC signing, delivery retries | `add_webhooks(app)` |
132
+ | **💾 Cache** | Redis/memory, decorators, namespacing | `init_cache()` |
133
+ | **📊 Observability** | Prometheus, Grafana dashboards, OTEL | Built-in |
134
+ | **📁 Storage** | S3, local, memory backends | `add_storage(app)` |
135
+ | **🏢 Multi-tenancy** | Tenant isolation, scoped queries | Built-in |
136
+ | **🚦 Rate Limiting** | Per-user, per-endpoint, headers | Built-in |
137
+
138
+ ## 🚀 30-Second Example
139
+
140
+ Build a complete SaaS backend:
141
+
142
+ ```python
143
+ from fastapi import Depends
144
+ from svc_infra.api.fastapi.ease import easy_service_app
145
+ from svc_infra.api.fastapi.db.sql.add import add_sql_db
146
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
147
+ from svc_infra.jobs.easy import easy_jobs
148
+ from svc_infra.webhooks.fastapi import require_signature
149
+
150
+ # Create app with batteries included
151
+ app = easy_service_app(name="MySaaS", release="1.0.0")
152
+
153
+ # Add infrastructure
154
+ add_sql_db(app) # PostgreSQL with migrations
155
+ add_auth_users(app) # Full auth system
156
+ queue, scheduler = easy_jobs() # Background jobs
157
+
158
+ # Your actual business logic
159
+ @app.post("/api/process")
160
+ async def process_data(user=Depends(current_active_user)):
161
+ job = queue.enqueue("heavy_task", {"user_id": user.id})
162
+ return {"job_id": job.id, "status": "queued"}
163
+
164
+ # Webhook endpoint with signature verification
165
+ @app.post("/webhooks/stripe")
166
+ async def stripe_webhook(payload=Depends(require_signature(lambda: ["whsec_..."]))):
167
+ queue.enqueue("process_payment", payload)
168
+ return {"received": True}
169
+ ```
170
+
171
+ **That's a production-ready API** with auth, database, background jobs, and webhook handling.
172
+
173
+ ## 📚 Feature Highlights
174
+
175
+ ### 🔐 Authentication & Security
176
+
177
+ Full auth system with zero boilerplate:
178
+
179
+ ```python
180
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
181
+
182
+ add_auth_users(app) # Registers /auth/* routes automatically
183
+
184
+ @app.get("/me")
185
+ async def get_profile(user=Depends(current_active_user)):
186
+ return {"email": user.email, "mfa_enabled": user.mfa_enabled}
187
+ ```
188
+
189
+ **Includes:** JWT tokens, session cookies, OAuth/OIDC (Google, GitHub, etc.), MFA/TOTP, password policies, account lockout, key rotation.
190
+
191
+ ### 💳 Usage-Based Billing
192
+
193
+ Track usage and generate invoices:
194
+
195
+ ```python
196
+ from svc_infra.billing import BillingService
197
+
198
+ billing = BillingService(session=db, tenant_id="tenant_123")
199
+
200
+ # Record API usage (idempotent)
201
+ billing.record_usage(metric="api_calls", amount=1, idempotency_key="req_abc")
202
+
203
+ # Generate monthly invoice
204
+ invoice = billing.generate_monthly_invoice(
205
+ period_start=datetime(2025, 1, 1),
206
+ period_end=datetime(2025, 2, 1),
207
+ )
208
+ ```
209
+
210
+ **Includes:** Usage events, aggregation, plans & entitlements, subscriptions, invoices, Stripe sync hooks.
211
+
212
+ ### ⚡ Background Jobs
213
+
214
+ Redis-backed job queue with retries:
215
+
216
+ ```python
217
+ from svc_infra.jobs.easy import easy_jobs
218
+
219
+ queue, scheduler = easy_jobs() # Auto-detects Redis or uses memory
220
+
221
+ # Enqueue work
222
+ queue.enqueue("send_email", {"to": "user@example.com", "template": "welcome"})
223
+
224
+ # Schedule recurring tasks
225
+ scheduler.add("cleanup", interval_seconds=3600, target="myapp.tasks:cleanup")
226
+ ```
227
+
228
+ ```bash
229
+ # Run the worker
230
+ svc-infra jobs run
231
+ ```
232
+
233
+ **Includes:** Visibility timeout, exponential backoff, dead letter queue, interval scheduler, CLI worker.
234
+
235
+ ### 🔗 Webhooks
236
+
237
+ Send and receive webhooks with proper security:
238
+
239
+ ```python
240
+ from svc_infra.webhooks import add_webhooks, WebhookService
241
+
242
+ add_webhooks(app) # Adds subscription management routes
243
+
244
+ # Publish events
245
+ webhook_service.publish("invoice.paid", {"invoice_id": "inv_123"})
246
+
247
+ # Verify incoming webhooks
248
+ @app.post("/webhooks/external")
249
+ async def receive(payload=Depends(require_signature(lambda: ["secret1", "secret2"]))):
250
+ return {"ok": True}
251
+ ```
252
+
253
+ **Includes:** Subscription store, HMAC-SHA256 signing, delivery retries, idempotent processing.
254
+
255
+ ### 📊 Observability
256
+
257
+ Production monitoring out of the box:
258
+
259
+ ```python
260
+ app = easy_service_app(name="MyAPI", release="1.0.0")
261
+ # Prometheus metrics at /metrics
262
+ # Health checks at /healthz, /readyz, /startupz
263
+ # Request tracing with OpenTelemetry
264
+ ```
265
+
266
+ ```bash
267
+ # Generate Grafana dashboards
268
+ svc-infra obs dashboard --service myapi --output ./dashboards/
269
+ ```
270
+
271
+ **Includes:** Prometheus metrics, Grafana dashboard generator, OTEL integration, SLO helpers.
272
+
273
+ ## ⚙️ Configuration
274
+
275
+ Everything is configurable via environment variables:
276
+
277
+ ```bash
278
+ # Database
279
+ SQL_URL=postgresql://user:pass@localhost/mydb
280
+ MONGO_URL=mongodb://localhost:27017
281
+
282
+ # Auth
283
+ AUTH_JWT__SECRET=your-secret-key
284
+ AUTH_SMTP_HOST=smtp.sendgrid.net
285
+
286
+ # Jobs
287
+ JOBS_DRIVER=redis
288
+ REDIS_URL=redis://localhost:6379
289
+
290
+ # Storage
291
+ STORAGE_BACKEND=s3
292
+ STORAGE_S3_BUCKET=my-uploads
293
+
294
+ # Observability
295
+ ENABLE_OBS=true
296
+ METRICS_PATH=/metrics
297
+ ```
298
+
299
+ See the [Environment Reference](docs/environment.md) for all options.
300
+
301
+ ## 📖 Documentation
302
+
303
+ | Module | Description | Guide |
304
+ |--------|-------------|-------|
305
+ | **API** | FastAPI bootstrap, middleware, versioning | [docs/api.md](docs/api.md) |
306
+ | **Auth** | Sessions, OAuth/OIDC, MFA, API keys | [docs/auth.md](docs/auth.md) |
307
+ | **Billing** | Usage tracking, subscriptions, invoices | [docs/billing.md](docs/billing.md) |
308
+ | **Database** | SQL + MongoDB, migrations, patterns | [docs/database.md](docs/database.md) |
309
+ | **Jobs** | Background tasks, scheduling | [docs/jobs.md](docs/jobs.md) |
310
+ | **Webhooks** | Publishing, signing, verification | [docs/webhooks.md](docs/webhooks.md) |
311
+ | **Cache** | Redis/memory caching, TTL helpers | [docs/cache.md](docs/cache.md) |
312
+ | **Storage** | S3, local, memory file storage | [docs/storage.md](docs/storage.md) |
313
+ | **Observability** | Metrics, tracing, dashboards | [docs/observability.md](docs/observability.md) |
314
+ | **Security** | Password policy, headers, MFA | [docs/security.md](docs/security.md) |
315
+ | **Tenancy** | Multi-tenant isolation | [docs/tenancy.md](docs/tenancy.md) |
316
+ | **CLI** | Command-line tools | [docs/cli.md](docs/cli.md) |
317
+
318
+ ## 🏃 Running the Example
319
+
320
+ See all features working together:
321
+
322
+ ```bash
323
+ git clone https://github.com/nfraxlab/svc-infra.git
324
+ cd svc-infra
325
+
326
+ # Setup and run
327
+ make setup-template # Creates DB, runs migrations
328
+ make run-template # Starts at http://localhost:8001
329
+ ```
330
+
331
+ Visit http://localhost:8001/docs to explore the API.
332
+
333
+ ## 🤝 Related Packages
334
+
335
+ svc-infra is part of the **nfrax** infrastructure suite:
336
+
337
+ | Package | Purpose |
338
+ |---------|---------|
339
+ | **[svc-infra](https://github.com/nfraxlab/svc-infra)** | Backend infrastructure (auth, billing, jobs, webhooks) |
340
+ | **[ai-infra](https://github.com/nfraxlab/ai-infra)** | AI/LLM infrastructure (agents, tools, RAG, MCP) |
341
+ | **[fin-infra](https://github.com/nfraxlab/fin-infra)** | Financial infrastructure (banking, portfolio, insights) |
342
+
343
+ ## 📄 License
344
+
345
+ MIT License - use it for anything.
346
+
347
+ ---
348
+
349
+ <div align="center">
350
+
351
+ **Built with ❤️ by [nfraxlab](https://github.com/nfraxlab)**
352
+
353
+ [⭐ Star us on GitHub](https://github.com/nfraxlab/svc-infra) · [📦 View on PyPI](https://pypi.org/project/svc-infra/)
354
+
355
+ </div>
356
+
@@ -0,0 +1,271 @@
1
+ <div align="center">
2
+
3
+ # svc-infra
4
+
5
+ ### Production-ready FastAPI infrastructure in one import
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/svc-infra.svg)](https://pypi.org/project/svc-infra/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://static.pepy.tech/badge/svc-infra/month)](https://pepy.tech/project/svc-infra)
8
+
9
+ **Stop rebuilding auth, billing, webhooks, and background jobs for every project.**
10
+
11
+ [Documentation](docs/) · [Examples](examples/) · [PyPI](https://pypi.org/project/svc-infra/)
12
+
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## Why svc-infra?
18
+
19
+ Every FastAPI project needs the same things: authentication, database setup, background jobs, caching, webhooks, billing... You've written this code before. Multiple times.
20
+
21
+ **svc-infra** packages battle-tested infrastructure used in production, so you can focus on your actual product:
22
+
23
+ ```python
24
+ from svc_infra.api.fastapi.ease import easy_service_app
25
+
26
+ app = easy_service_app(name="MyAPI", release="1.0.0")
27
+ # ✅ Health checks, CORS, security headers, structured logging
28
+ # ✅ Prometheus metrics, OpenTelemetry tracing
29
+ # ✅ Request IDs, idempotency middleware
30
+ # That's it. Ship it.
31
+ ```
32
+
33
+ ## ⚡ Quick Install
34
+
35
+ ```bash
36
+ pip install svc-infra
37
+ ```
38
+
39
+ ## 🎯 What's Included
40
+
41
+ | Feature | What You Get | One-liner |
42
+ |---------|-------------|-----------|
43
+ | **🔐 Auth** | JWT, sessions, OAuth/OIDC, MFA, API keys | `add_auth_users(app)` |
44
+ | **💳 Billing** | Usage tracking, subscriptions, invoices, Stripe sync | `add_billing(app)` |
45
+ | **📦 Database** | PostgreSQL + MongoDB, migrations, inbox/outbox | `add_sql_db(app)` |
46
+ | **⚡ Jobs** | Background tasks, scheduling, retries, DLQ | `easy_jobs()` |
47
+ | **🔗 Webhooks** | Subscriptions, HMAC signing, delivery retries | `add_webhooks(app)` |
48
+ | **💾 Cache** | Redis/memory, decorators, namespacing | `init_cache()` |
49
+ | **📊 Observability** | Prometheus, Grafana dashboards, OTEL | Built-in |
50
+ | **📁 Storage** | S3, local, memory backends | `add_storage(app)` |
51
+ | **🏢 Multi-tenancy** | Tenant isolation, scoped queries | Built-in |
52
+ | **🚦 Rate Limiting** | Per-user, per-endpoint, headers | Built-in |
53
+
54
+ ## 🚀 30-Second Example
55
+
56
+ Build a complete SaaS backend:
57
+
58
+ ```python
59
+ from fastapi import Depends
60
+ from svc_infra.api.fastapi.ease import easy_service_app
61
+ from svc_infra.api.fastapi.db.sql.add import add_sql_db
62
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
63
+ from svc_infra.jobs.easy import easy_jobs
64
+ from svc_infra.webhooks.fastapi import require_signature
65
+
66
+ # Create app with batteries included
67
+ app = easy_service_app(name="MySaaS", release="1.0.0")
68
+
69
+ # Add infrastructure
70
+ add_sql_db(app) # PostgreSQL with migrations
71
+ add_auth_users(app) # Full auth system
72
+ queue, scheduler = easy_jobs() # Background jobs
73
+
74
+ # Your actual business logic
75
+ @app.post("/api/process")
76
+ async def process_data(user=Depends(current_active_user)):
77
+ job = queue.enqueue("heavy_task", {"user_id": user.id})
78
+ return {"job_id": job.id, "status": "queued"}
79
+
80
+ # Webhook endpoint with signature verification
81
+ @app.post("/webhooks/stripe")
82
+ async def stripe_webhook(payload=Depends(require_signature(lambda: ["whsec_..."]))):
83
+ queue.enqueue("process_payment", payload)
84
+ return {"received": True}
85
+ ```
86
+
87
+ **That's a production-ready API** with auth, database, background jobs, and webhook handling.
88
+
89
+ ## 📚 Feature Highlights
90
+
91
+ ### 🔐 Authentication & Security
92
+
93
+ Full auth system with zero boilerplate:
94
+
95
+ ```python
96
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
97
+
98
+ add_auth_users(app) # Registers /auth/* routes automatically
99
+
100
+ @app.get("/me")
101
+ async def get_profile(user=Depends(current_active_user)):
102
+ return {"email": user.email, "mfa_enabled": user.mfa_enabled}
103
+ ```
104
+
105
+ **Includes:** JWT tokens, session cookies, OAuth/OIDC (Google, GitHub, etc.), MFA/TOTP, password policies, account lockout, key rotation.
106
+
107
+ ### 💳 Usage-Based Billing
108
+
109
+ Track usage and generate invoices:
110
+
111
+ ```python
112
+ from svc_infra.billing import BillingService
113
+
114
+ billing = BillingService(session=db, tenant_id="tenant_123")
115
+
116
+ # Record API usage (idempotent)
117
+ billing.record_usage(metric="api_calls", amount=1, idempotency_key="req_abc")
118
+
119
+ # Generate monthly invoice
120
+ invoice = billing.generate_monthly_invoice(
121
+ period_start=datetime(2025, 1, 1),
122
+ period_end=datetime(2025, 2, 1),
123
+ )
124
+ ```
125
+
126
+ **Includes:** Usage events, aggregation, plans & entitlements, subscriptions, invoices, Stripe sync hooks.
127
+
128
+ ### ⚡ Background Jobs
129
+
130
+ Redis-backed job queue with retries:
131
+
132
+ ```python
133
+ from svc_infra.jobs.easy import easy_jobs
134
+
135
+ queue, scheduler = easy_jobs() # Auto-detects Redis or uses memory
136
+
137
+ # Enqueue work
138
+ queue.enqueue("send_email", {"to": "user@example.com", "template": "welcome"})
139
+
140
+ # Schedule recurring tasks
141
+ scheduler.add("cleanup", interval_seconds=3600, target="myapp.tasks:cleanup")
142
+ ```
143
+
144
+ ```bash
145
+ # Run the worker
146
+ svc-infra jobs run
147
+ ```
148
+
149
+ **Includes:** Visibility timeout, exponential backoff, dead letter queue, interval scheduler, CLI worker.
150
+
151
+ ### 🔗 Webhooks
152
+
153
+ Send and receive webhooks with proper security:
154
+
155
+ ```python
156
+ from svc_infra.webhooks import add_webhooks, WebhookService
157
+
158
+ add_webhooks(app) # Adds subscription management routes
159
+
160
+ # Publish events
161
+ webhook_service.publish("invoice.paid", {"invoice_id": "inv_123"})
162
+
163
+ # Verify incoming webhooks
164
+ @app.post("/webhooks/external")
165
+ async def receive(payload=Depends(require_signature(lambda: ["secret1", "secret2"]))):
166
+ return {"ok": True}
167
+ ```
168
+
169
+ **Includes:** Subscription store, HMAC-SHA256 signing, delivery retries, idempotent processing.
170
+
171
+ ### 📊 Observability
172
+
173
+ Production monitoring out of the box:
174
+
175
+ ```python
176
+ app = easy_service_app(name="MyAPI", release="1.0.0")
177
+ # Prometheus metrics at /metrics
178
+ # Health checks at /healthz, /readyz, /startupz
179
+ # Request tracing with OpenTelemetry
180
+ ```
181
+
182
+ ```bash
183
+ # Generate Grafana dashboards
184
+ svc-infra obs dashboard --service myapi --output ./dashboards/
185
+ ```
186
+
187
+ **Includes:** Prometheus metrics, Grafana dashboard generator, OTEL integration, SLO helpers.
188
+
189
+ ## ⚙️ Configuration
190
+
191
+ Everything is configurable via environment variables:
192
+
193
+ ```bash
194
+ # Database
195
+ SQL_URL=postgresql://user:pass@localhost/mydb
196
+ MONGO_URL=mongodb://localhost:27017
197
+
198
+ # Auth
199
+ AUTH_JWT__SECRET=your-secret-key
200
+ AUTH_SMTP_HOST=smtp.sendgrid.net
201
+
202
+ # Jobs
203
+ JOBS_DRIVER=redis
204
+ REDIS_URL=redis://localhost:6379
205
+
206
+ # Storage
207
+ STORAGE_BACKEND=s3
208
+ STORAGE_S3_BUCKET=my-uploads
209
+
210
+ # Observability
211
+ ENABLE_OBS=true
212
+ METRICS_PATH=/metrics
213
+ ```
214
+
215
+ See the [Environment Reference](docs/environment.md) for all options.
216
+
217
+ ## 📖 Documentation
218
+
219
+ | Module | Description | Guide |
220
+ |--------|-------------|-------|
221
+ | **API** | FastAPI bootstrap, middleware, versioning | [docs/api.md](docs/api.md) |
222
+ | **Auth** | Sessions, OAuth/OIDC, MFA, API keys | [docs/auth.md](docs/auth.md) |
223
+ | **Billing** | Usage tracking, subscriptions, invoices | [docs/billing.md](docs/billing.md) |
224
+ | **Database** | SQL + MongoDB, migrations, patterns | [docs/database.md](docs/database.md) |
225
+ | **Jobs** | Background tasks, scheduling | [docs/jobs.md](docs/jobs.md) |
226
+ | **Webhooks** | Publishing, signing, verification | [docs/webhooks.md](docs/webhooks.md) |
227
+ | **Cache** | Redis/memory caching, TTL helpers | [docs/cache.md](docs/cache.md) |
228
+ | **Storage** | S3, local, memory file storage | [docs/storage.md](docs/storage.md) |
229
+ | **Observability** | Metrics, tracing, dashboards | [docs/observability.md](docs/observability.md) |
230
+ | **Security** | Password policy, headers, MFA | [docs/security.md](docs/security.md) |
231
+ | **Tenancy** | Multi-tenant isolation | [docs/tenancy.md](docs/tenancy.md) |
232
+ | **CLI** | Command-line tools | [docs/cli.md](docs/cli.md) |
233
+
234
+ ## 🏃 Running the Example
235
+
236
+ See all features working together:
237
+
238
+ ```bash
239
+ git clone https://github.com/nfraxlab/svc-infra.git
240
+ cd svc-infra
241
+
242
+ # Setup and run
243
+ make setup-template # Creates DB, runs migrations
244
+ make run-template # Starts at http://localhost:8001
245
+ ```
246
+
247
+ Visit http://localhost:8001/docs to explore the API.
248
+
249
+ ## 🤝 Related Packages
250
+
251
+ svc-infra is part of the **nfrax** infrastructure suite:
252
+
253
+ | Package | Purpose |
254
+ |---------|---------|
255
+ | **[svc-infra](https://github.com/nfraxlab/svc-infra)** | Backend infrastructure (auth, billing, jobs, webhooks) |
256
+ | **[ai-infra](https://github.com/nfraxlab/ai-infra)** | AI/LLM infrastructure (agents, tools, RAG, MCP) |
257
+ | **[fin-infra](https://github.com/nfraxlab/fin-infra)** | Financial infrastructure (banking, portfolio, insights) |
258
+
259
+ ## 📄 License
260
+
261
+ MIT License - use it for anything.
262
+
263
+ ---
264
+
265
+ <div align="center">
266
+
267
+ **Built with ❤️ by [nfraxlab](https://github.com/nfraxlab)**
268
+
269
+ [⭐ Star us on GitHub](https://github.com/nfraxlab/svc-infra) · [📦 View on PyPI](https://pypi.org/project/svc-infra/)
270
+
271
+ </div>