svc-infra 0.1.672__tar.gz → 1.6.1__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 (424) hide show
  1. svc_infra-1.6.1/LICENSE +21 -0
  2. svc_infra-1.6.1/PKG-INFO +362 -0
  3. svc_infra-1.6.1/README.md +277 -0
  4. svc_infra-1.6.1/pyproject.toml +259 -0
  5. svc_infra-1.6.1/src/svc_infra/__init__.py +59 -0
  6. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/README.md +9 -9
  7. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/models.py +68 -38
  8. svc_infra-1.6.1/src/svc_infra/apf_payments/provider/__init__.py +4 -0
  9. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/provider/aiydan.py +39 -23
  10. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/provider/base.py +8 -3
  11. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/provider/registry.py +3 -5
  12. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/provider/stripe.py +74 -52
  13. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/schemas.py +84 -83
  14. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/service.py +27 -16
  15. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/settings.py +12 -11
  16. svc_infra-1.6.1/src/svc_infra/api/__init__.py +61 -0
  17. svc_infra-1.6.1/src/svc_infra/api/fastapi/__init__.py +65 -0
  18. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/admin/add.py +25 -16
  19. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/apf_payments/router.py +44 -33
  20. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/apf_payments/setup.py +10 -7
  21. svc_infra-1.6.1/src/svc_infra/api/fastapi/auth/__init__.py +65 -0
  22. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/_cookies.py +1 -3
  23. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/add.py +14 -11
  24. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/gaurd.py +30 -18
  25. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/models.py +3 -4
  26. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +13 -9
  27. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/router.py +9 -8
  28. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/security.py +4 -7
  29. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/utils.py +5 -3
  30. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/policy.py +15 -0
  31. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/providers.py +3 -3
  32. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +19 -21
  33. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +78 -42
  34. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/routers/session_router.py +6 -5
  35. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/security.py +25 -15
  36. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/sender.py +5 -0
  37. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/settings.py +18 -19
  38. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/state.py +5 -4
  39. svc_infra-1.6.1/src/svc_infra/api/fastapi/auth/ws_security.py +275 -0
  40. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/billing/router.py +15 -8
  41. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/__init__.py +5 -1
  42. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/http.py +10 -9
  43. svc_infra-1.6.1/src/svc_infra/api/fastapi/db/nosql/__init__.py +46 -0
  44. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +3 -4
  45. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +39 -21
  46. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/README.md +1 -1
  47. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/__init__.py +5 -1
  48. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/add.py +25 -10
  49. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/crud_router.py +57 -44
  50. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/session.py +3 -2
  51. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/users.py +18 -9
  52. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +26 -14
  53. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/docs/add.py +12 -9
  54. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/docs/landing.py +5 -5
  55. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/docs/scoped.py +38 -34
  56. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dual/__init__.py +12 -2
  57. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dual/dualize.py +2 -2
  58. svc_infra-1.6.1/src/svc_infra/api/fastapi/dual/protected.py +209 -0
  59. svc_infra-1.6.1/src/svc_infra/api/fastapi/dual/public.py +47 -0
  60. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dual/router.py +18 -8
  61. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dx.py +33 -2
  62. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/ease.py +59 -7
  63. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/http/concurrency.py +2 -1
  64. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/http/conditional.py +2 -2
  65. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/debug.py +4 -1
  66. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +2 -5
  67. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +9 -7
  68. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/graceful_shutdown.py +13 -5
  69. svc_infra-1.6.1/src/svc_infra/api/fastapi/middleware/idempotency.py +208 -0
  70. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +14 -14
  71. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +4 -2
  72. svc_infra-1.6.1/src/svc_infra/api/fastapi/middleware/ratelimit.py +158 -0
  73. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +32 -6
  74. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +3 -3
  75. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/timeout.py +52 -56
  76. svc_infra-1.6.1/src/svc_infra/api/fastapi/object_router.py +1060 -0
  77. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/apply.py +4 -3
  78. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/conventions.py +13 -6
  79. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/models.py +6 -0
  80. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/mutators.py +31 -18
  81. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/pipeline.py +2 -2
  82. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/responses.py +4 -6
  83. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/openapi/security.py +1 -1
  84. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/ops/add.py +6 -6
  85. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/pagination.py +44 -31
  86. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/routers/__init__.py +16 -10
  87. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/setup.py +149 -56
  88. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/tenancy/add.py +3 -2
  89. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/tenancy/context.py +11 -10
  90. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/versioned.py +3 -2
  91. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/__init__.py +3 -1
  92. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/env.py +70 -4
  93. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/logging/add.py +10 -2
  94. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/logging/filter.py +1 -1
  95. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/logging/formats.py +13 -5
  96. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/root.py +3 -3
  97. svc_infra-1.6.1/src/svc_infra/billing/__init__.py +40 -0
  98. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/billing/async_service.py +51 -8
  99. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/billing/jobs.py +19 -18
  100. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/billing/models.py +31 -16
  101. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/billing/quotas.py +5 -5
  102. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/billing/schemas.py +7 -6
  103. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/README.md +32 -32
  104. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/__init__.py +17 -5
  105. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/add.py +19 -10
  106. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/backend.py +4 -5
  107. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/decorators.py +75 -38
  108. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/demo.py +2 -2
  109. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/keys.py +2 -2
  110. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/recache.py +26 -27
  111. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/resources.py +6 -5
  112. svc_infra-1.6.1/src/svc_infra/cache/tags.py +52 -0
  113. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/ttl.py +2 -3
  114. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cache/utils.py +6 -3
  115. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/__init__.py +12 -0
  116. svc_infra-1.6.1/src/svc_infra/cli/cmds/__init__.py +55 -0
  117. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +2 -2
  118. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +14 -11
  119. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +5 -6
  120. svc_infra-1.6.1/src/svc_infra/cli/cmds/db/ops_cmds.py +267 -0
  121. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +19 -20
  122. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +12 -12
  123. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +10 -10
  124. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/docs/docs_cmds.py +6 -7
  125. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/dx/dx_cmds.py +15 -4
  126. svc_infra-1.6.1/src/svc_infra/cli/cmds/health/__init__.py +179 -0
  127. svc_infra-1.6.1/src/svc_infra/cli/cmds/health/health_cmds.py +8 -0
  128. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +1 -2
  129. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/obs/obs_cmds.py +27 -10
  130. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/foundation/runner.py +4 -5
  131. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/foundation/typer_bootstrap.py +1 -2
  132. svc_infra-1.6.1/src/svc_infra/data/__init__.py +83 -0
  133. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/data/add.py +7 -7
  134. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/data/backup.py +11 -8
  135. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/data/erasure.py +4 -3
  136. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/data/fixtures.py +7 -5
  137. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/data/retention.py +9 -8
  138. svc_infra-1.6.1/src/svc_infra/db/__init__.py +15 -0
  139. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/crud_schema.py +14 -13
  140. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/__init__.py +2 -0
  141. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/constants.py +1 -1
  142. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/core.py +19 -5
  143. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/indexes.py +12 -9
  144. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/management.py +4 -4
  145. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/client.py +21 -4
  146. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/settings.py +1 -1
  147. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/repository.py +46 -27
  148. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/resource.py +28 -16
  149. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/scaffold.py +14 -12
  150. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/service.py +2 -1
  151. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/service_with_hooks.py +4 -3
  152. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/utils.py +4 -4
  153. svc_infra-1.6.1/src/svc_infra/db/ops.py +380 -0
  154. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/outbox.py +15 -14
  155. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/apikey.py +34 -15
  156. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/authref.py +8 -6
  157. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/constants.py +5 -1
  158. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/core.py +13 -13
  159. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/management.py +5 -6
  160. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/repository.py +48 -22
  161. svc_infra-1.6.1/src/svc_infra/db/sql/resource.py +56 -0
  162. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/scaffold.py +11 -11
  163. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/service.py +2 -1
  164. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/service_with_hooks.py +4 -3
  165. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/tenant.py +2 -1
  166. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/uniq.py +8 -7
  167. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/uniq_hooks.py +12 -11
  168. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/utils.py +87 -43
  169. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/utils.py +3 -3
  170. svc_infra-1.6.1/src/svc_infra/deploy/__init__.py +533 -0
  171. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/documents/add.py +14 -9
  172. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/documents/ease.py +8 -8
  173. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/documents/models.py +3 -3
  174. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/documents/storage.py +10 -10
  175. svc_infra-1.6.1/src/svc_infra/dx/__init__.py +58 -0
  176. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/dx/changelog.py +2 -2
  177. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/dx/checks.py +3 -2
  178. svc_infra-1.6.1/src/svc_infra/exceptions.py +141 -0
  179. svc_infra-1.6.1/src/svc_infra/health/__init__.py +863 -0
  180. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/http/client.py +38 -9
  181. svc_infra-1.6.1/src/svc_infra/jobs/__init__.py +79 -0
  182. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/builtins/outbox_processor.py +2 -2
  183. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/builtins/webhook_delivery.py +4 -1
  184. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/easy.py +1 -0
  185. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/loader.py +8 -4
  186. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/queue.py +43 -12
  187. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/redis_queue.py +84 -33
  188. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/runner.py +5 -5
  189. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/scheduler.py +18 -6
  190. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/jobs/worker.py +1 -1
  191. svc_infra-1.6.1/src/svc_infra/loaders/__init__.py +186 -0
  192. svc_infra-1.6.1/src/svc_infra/loaders/base.py +143 -0
  193. svc_infra-1.6.1/src/svc_infra/loaders/github.py +309 -0
  194. svc_infra-1.6.1/src/svc_infra/loaders/models.py +147 -0
  195. svc_infra-1.6.1/src/svc_infra/loaders/url.py +229 -0
  196. svc_infra-1.6.1/src/svc_infra/logging/__init__.py +375 -0
  197. svc_infra-1.6.1/src/svc_infra/mcp/__init__.py +82 -0
  198. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/mcp/svc_infra_mcp.py +5 -4
  199. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/README.md +1 -1
  200. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/add.py +17 -7
  201. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/cloud_dash.py +4 -1
  202. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics/__init__.py +6 -7
  203. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics/asgi.py +8 -7
  204. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics/base.py +13 -13
  205. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics/http.py +3 -3
  206. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics/sqlalchemy.py +14 -13
  207. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/metrics.py +9 -8
  208. svc_infra-1.6.1/src/svc_infra/resilience/__init__.py +44 -0
  209. svc_infra-1.6.1/src/svc_infra/resilience/circuit_breaker.py +328 -0
  210. svc_infra-1.6.1/src/svc_infra/resilience/retry.py +289 -0
  211. svc_infra-1.6.1/src/svc_infra/security/__init__.py +167 -0
  212. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/add.py +18 -6
  213. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/audit.py +97 -18
  214. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/audit_service.py +10 -9
  215. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/hibp.py +9 -4
  216. svc_infra-1.6.1/src/svc_infra/security/jwt_rotation.py +102 -0
  217. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/lockout.py +23 -16
  218. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/models.py +55 -42
  219. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/oauth_models.py +23 -15
  220. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/org_invites.py +12 -12
  221. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/passwords.py +3 -3
  222. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/permissions.py +30 -7
  223. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/session.py +7 -8
  224. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/signed_cookies.py +26 -6
  225. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/add.py +4 -4
  226. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/backends/local.py +10 -10
  227. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/backends/memory.py +3 -4
  228. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/backends/s3.py +17 -12
  229. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/base.py +2 -2
  230. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/easy.py +3 -4
  231. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/settings.py +14 -14
  232. svc_infra-1.6.1/src/svc_infra/testing/__init__.py +682 -0
  233. svc_infra-1.6.1/src/svc_infra/utils.py +188 -0
  234. svc_infra-1.6.1/src/svc_infra/webhooks/__init__.py +69 -0
  235. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/webhooks/add.py +57 -52
  236. svc_infra-1.6.1/src/svc_infra/webhooks/encryption.py +115 -0
  237. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/webhooks/fastapi.py +1 -1
  238. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/webhooks/router.py +3 -3
  239. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/webhooks/service.py +32 -7
  240. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/webhooks/signing.py +10 -6
  241. svc_infra-1.6.1/src/svc_infra/websocket/__init__.py +79 -0
  242. svc_infra-1.6.1/src/svc_infra/websocket/add.py +139 -0
  243. svc_infra-1.6.1/src/svc_infra/websocket/client.py +283 -0
  244. svc_infra-1.6.1/src/svc_infra/websocket/config.py +57 -0
  245. svc_infra-1.6.1/src/svc_infra/websocket/easy.py +76 -0
  246. svc_infra-1.6.1/src/svc_infra/websocket/exceptions.py +61 -0
  247. svc_infra-1.6.1/src/svc_infra/websocket/manager.py +343 -0
  248. svc_infra-1.6.1/src/svc_infra/websocket/models.py +49 -0
  249. svc_infra-0.1.672/PKG-INFO +0 -160
  250. svc_infra-0.1.672/README.md +0 -80
  251. svc_infra-0.1.672/pyproject.toml +0 -153
  252. svc_infra-0.1.672/src/svc_infra/__init__.py +0 -3
  253. svc_infra-0.1.672/src/svc_infra/apf_payments/provider/__init__.py +0 -4
  254. svc_infra-0.1.672/src/svc_infra/api/fastapi/__init__.py +0 -31
  255. svc_infra-0.1.672/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -8
  256. svc_infra-0.1.672/src/svc_infra/api/fastapi/dual/protected.py +0 -96
  257. svc_infra-0.1.672/src/svc_infra/api/fastapi/dual/public.py +0 -22
  258. svc_infra-0.1.672/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -123
  259. svc_infra-0.1.672/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -126
  260. svc_infra-0.1.672/src/svc_infra/billing/__init__.py +0 -23
  261. svc_infra-0.1.672/src/svc_infra/billing/service.py +0 -115
  262. svc_infra-0.1.672/src/svc_infra/cache/tags.py +0 -77
  263. svc_infra-0.1.672/src/svc_infra/cli/cmds/__init__.py +0 -28
  264. svc_infra-0.1.672/src/svc_infra/db/sql/resource.py +0 -41
  265. svc_infra-0.1.672/src/svc_infra/docs/acceptance-matrix.md +0 -88
  266. svc_infra-0.1.672/src/svc_infra/docs/acceptance.md +0 -44
  267. svc_infra-0.1.672/src/svc_infra/docs/admin.md +0 -425
  268. svc_infra-0.1.672/src/svc_infra/docs/adr/0002-background-jobs-and-scheduling.md +0 -40
  269. svc_infra-0.1.672/src/svc_infra/docs/adr/0003-webhooks-framework.md +0 -24
  270. svc_infra-0.1.672/src/svc_infra/docs/adr/0004-tenancy-model.md +0 -42
  271. svc_infra-0.1.672/src/svc_infra/docs/adr/0005-data-lifecycle.md +0 -86
  272. svc_infra-0.1.672/src/svc_infra/docs/adr/0006-ops-slos-and-metrics.md +0 -47
  273. svc_infra-0.1.672/src/svc_infra/docs/adr/0007-docs-and-sdks.md +0 -83
  274. svc_infra-0.1.672/src/svc_infra/docs/adr/0008-billing-primitives.md +0 -143
  275. svc_infra-0.1.672/src/svc_infra/docs/adr/0009-acceptance-harness.md +0 -40
  276. svc_infra-0.1.672/src/svc_infra/docs/adr/0010-timeouts-and-resource-limits.md +0 -54
  277. svc_infra-0.1.672/src/svc_infra/docs/adr/0011-admin-scope-and-impersonation.md +0 -73
  278. svc_infra-0.1.672/src/svc_infra/docs/adr/0012-generic-file-storage.md +0 -498
  279. svc_infra-0.1.672/src/svc_infra/docs/api.md +0 -215
  280. svc_infra-0.1.672/src/svc_infra/docs/auth.md +0 -11
  281. svc_infra-0.1.672/src/svc_infra/docs/billing.md +0 -190
  282. svc_infra-0.1.672/src/svc_infra/docs/cache.md +0 -76
  283. svc_infra-0.1.672/src/svc_infra/docs/cli.md +0 -74
  284. svc_infra-0.1.672/src/svc_infra/docs/contributing.md +0 -34
  285. svc_infra-0.1.672/src/svc_infra/docs/data-lifecycle.md +0 -52
  286. svc_infra-0.1.672/src/svc_infra/docs/database.md +0 -14
  287. svc_infra-0.1.672/src/svc_infra/docs/docs-and-sdks.md +0 -62
  288. svc_infra-0.1.672/src/svc_infra/docs/documents.md +0 -697
  289. svc_infra-0.1.672/src/svc_infra/docs/environment.md +0 -114
  290. svc_infra-0.1.672/src/svc_infra/docs/getting-started.md +0 -63
  291. svc_infra-0.1.672/src/svc_infra/docs/idempotency.md +0 -111
  292. svc_infra-0.1.672/src/svc_infra/docs/jobs.md +0 -67
  293. svc_infra-0.1.672/src/svc_infra/docs/observability.md +0 -16
  294. svc_infra-0.1.672/src/svc_infra/docs/ops.md +0 -37
  295. svc_infra-0.1.672/src/svc_infra/docs/rate-limiting.md +0 -125
  296. svc_infra-0.1.672/src/svc_infra/docs/repo-review.md +0 -48
  297. svc_infra-0.1.672/src/svc_infra/docs/security.md +0 -176
  298. svc_infra-0.1.672/src/svc_infra/docs/storage.md +0 -982
  299. svc_infra-0.1.672/src/svc_infra/docs/tenancy.md +0 -35
  300. svc_infra-0.1.672/src/svc_infra/docs/timeouts-and-resource-limits.md +0 -147
  301. svc_infra-0.1.672/src/svc_infra/docs/versioned-integrations.md +0 -146
  302. svc_infra-0.1.672/src/svc_infra/docs/webhooks.md +0 -112
  303. svc_infra-0.1.672/src/svc_infra/obs/templates/sidecars/compose/__init__.py +0 -0
  304. svc_infra-0.1.672/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
  305. svc_infra-0.1.672/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
  306. svc_infra-0.1.672/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
  307. svc_infra-0.1.672/src/svc_infra/security/jwt_rotation.py +0 -53
  308. svc_infra-0.1.672/src/svc_infra/utils.py +0 -23
  309. svc_infra-0.1.672/src/svc_infra/webhooks/__init__.py +0 -16
  310. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/__init__.py +0 -0
  311. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/apf_payments/alembic.py +0 -0
  312. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/admin/__init__.py +0 -0
  313. {svc_infra-0.1.672/src/svc_infra/api → svc_infra-1.6.1/src/svc_infra/api/fastapi/apf_payments}/__init__.py +0 -0
  314. {svc_infra-0.1.672/src/svc_infra/api/fastapi/apf_payments → svc_infra-1.6.1/src/svc_infra/api/fastapi/auth/mfa}/__init__.py +0 -0
  315. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/mfa/verify.py +0 -0
  316. {svc_infra-0.1.672/src/svc_infra/api/fastapi/auth → svc_infra-1.6.1/src/svc_infra/api/fastapi/auth/routers}/__init__.py +0 -0
  317. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
  318. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/billing/setup.py +0 -0
  319. {svc_infra-0.1.672/src/svc_infra/api/fastapi/auth/mfa → svc_infra-1.6.1/src/svc_infra/api/fastapi/cache}/__init__.py +0 -0
  320. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/cache/add.py +0 -0
  321. {svc_infra-0.1.672/src/svc_infra/api/fastapi/auth/routers → svc_infra-1.6.1/src/svc_infra/api/fastapi/db/nosql/mongo}/__init__.py +0 -0
  322. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
  323. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/db/sql/health.py +0 -0
  324. {svc_infra-0.1.672/src/svc_infra/api/fastapi/cache → svc_infra-1.6.1/src/svc_infra/api/fastapi/docs}/__init__.py +0 -0
  325. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
  326. {svc_infra-0.1.672/src/svc_infra/api/fastapi/db/nosql/mongo → svc_infra-1.6.1/src/svc_infra/api/fastapi/http}/__init__.py +0 -0
  327. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
  328. {svc_infra-0.1.672/src/svc_infra/api/fastapi/docs → svc_infra-1.6.1/src/svc_infra/api/fastapi/middleware}/__init__.py +0 -0
  329. {svc_infra-0.1.672/src/svc_infra/api/fastapi/http → svc_infra-1.6.1/src/svc_infra/api/fastapi/middleware/errors}/__init__.py +0 -0
  330. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +0 -0
  331. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/middleware/request_id.py +0 -0
  332. {svc_infra-0.1.672/src/svc_infra/api/fastapi/middleware → svc_infra-1.6.1/src/svc_infra/api/fastapi/openapi}/__init__.py +0 -0
  333. {svc_infra-0.1.672/src/svc_infra/api/fastapi/middleware/errors → svc_infra-1.6.1/src/svc_infra/api/fastapi/paths}/__init__.py +0 -0
  334. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
  335. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
  336. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
  337. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/paths/user.py +0 -0
  338. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
  339. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/README.md +0 -0
  340. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/app/logging/__init__.py +0 -0
  341. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/bundled_docs/README.md +0 -0
  342. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/bundled_docs/__init__.py +0 -0
  343. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/bundled_docs/getting-started.md +0 -0
  344. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/__main__.py +0 -0
  345. {svc_infra-0.1.672/src/svc_infra/api/fastapi/openapi → svc_infra-1.6.1/src/svc_infra/cli/cmds/db}/__init__.py +0 -0
  346. {svc_infra-0.1.672/src/svc_infra/api/fastapi/paths → svc_infra-1.6.1/src/svc_infra/cli/cmds/db/nosql}/__init__.py +0 -0
  347. {svc_infra-0.1.672/src/svc_infra/cli/cmds/db → svc_infra-1.6.1/src/svc_infra/cli/cmds/db/nosql/mongo}/__init__.py +0 -0
  348. {svc_infra-0.1.672/src/svc_infra/cli/cmds/db/nosql → svc_infra-1.6.1/src/svc_infra/cli/cmds/db/sql}/__init__.py +0 -0
  349. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/dx/__init__.py +0 -0
  350. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/help.py +0 -0
  351. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
  352. {svc_infra-0.1.672/src/svc_infra/cli/cmds/db/nosql/mongo → svc_infra-1.6.1/src/svc_infra/cli/cmds/obs}/__init__.py +0 -0
  353. {svc_infra-0.1.672/src/svc_infra/cli/cmds/db/sql → svc_infra-1.6.1/src/svc_infra/cli/cmds/sdk}/__init__.py +0 -0
  354. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/cli/cmds/sdk/sdk_cmds.py +0 -0
  355. {svc_infra-0.1.672/src/svc_infra/cli/cmds/obs → svc_infra-1.6.1/src/svc_infra/cli/foundation}/__init__.py +0 -0
  356. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/inbox.py +0 -0
  357. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/base.py +0 -0
  358. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/README.md +0 -0
  359. {svc_infra-0.1.672/src/svc_infra/cli/cmds/sdk → svc_infra-1.6.1/src/svc_infra/db/nosql/mongo}/__init__.py +0 -0
  360. {svc_infra-0.1.672/src/svc_infra/cli/foundation → svc_infra-1.6.1/src/svc_infra/db/nosql/mongo/templates}/__init__.py +0 -0
  361. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
  362. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
  363. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
  364. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/nosql/types.py +0 -0
  365. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/README.md +0 -0
  366. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/__init__.py +0 -0
  367. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/base.py +0 -0
  368. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/__init__.py +0 -0
  369. {svc_infra-0.1.672/src/svc_infra/db → svc_infra-1.6.1/src/svc_infra/db/sql/templates/models_schemas}/__init__.py +0 -0
  370. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +0 -0
  371. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
  372. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
  373. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
  374. {svc_infra-0.1.672/src/svc_infra/db/nosql/mongo → svc_infra-1.6.1/src/svc_infra/db/sql/templates/setup}/__init__.py +0 -0
  375. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
  376. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +0 -0
  377. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +0 -0
  378. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
  379. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/types.py +0 -0
  380. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/db/sql/versioning.py +0 -0
  381. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/documents/__init__.py +0 -0
  382. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/dx/add.py +0 -0
  383. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/http/__init__.py +0 -0
  384. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/__init__.py +0 -0
  385. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/grafana/dashboards/http-overview.json +0 -0
  386. {svc_infra-0.1.672/src/svc_infra/db/nosql/mongo/templates → svc_infra-1.6.1/src/svc_infra/obs/providers}/__init__.py +0 -0
  387. {svc_infra-0.1.672/src/svc_infra/db/sql/templates/models_schemas → svc_infra-1.6.1/src/svc_infra/obs/providers/compose_cloud}/__init__.py +0 -0
  388. {svc_infra-0.1.672/src/svc_infra/db/sql/templates/setup → svc_infra-1.6.1/src/svc_infra/obs/providers/compose_cloud/templates}/__init__.py +0 -0
  389. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
  390. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
  391. {svc_infra-0.1.672/src/svc_infra/mcp → svc_infra-1.6.1/src/svc_infra/obs/providers/grafana}/__init__.py +0 -0
  392. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
  393. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
  394. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
  395. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
  396. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
  397. {svc_infra-0.1.672/src/svc_infra/obs/providers → svc_infra-1.6.1/src/svc_infra/obs/providers/grafana/dashboards}/__init__.py +0 -0
  398. {svc_infra-0.1.672/src/svc_infra/obs/providers/compose_cloud → svc_infra-1.6.1/src/svc_infra/obs/providers/grafana/templates}/__init__.py +0 -0
  399. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
  400. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
  401. {svc_infra-0.1.672/src/svc_infra/obs/providers/compose_cloud/templates → svc_infra-1.6.1/src/svc_infra/obs/providers/grafana/templates/provisioning}/__init__.py +0 -0
  402. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
  403. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
  404. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/settings.py +0 -0
  405. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
  406. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
  407. {svc_infra-0.1.672/src/svc_infra/obs/providers/grafana → svc_infra-1.6.1/src/svc_infra/obs/templates/sidecars}/__init__.py +0 -0
  408. {svc_infra-0.1.672/src/svc_infra/obs/providers/grafana/dashboards → svc_infra-1.6.1/src/svc_infra/obs/templates/sidecars/compose}/__init__.py +0 -0
  409. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
  410. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
  411. {svc_infra-0.1.672/src/svc_infra/obs/providers/grafana/templates → svc_infra-1.6.1/src/svc_infra/obs/templates/sidecars/fly}/__init__.py +0 -0
  412. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
  413. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
  414. {svc_infra-0.1.672/src/svc_infra/obs/providers/grafana/templates/provisioning → svc_infra-1.6.1/src/svc_infra/obs/templates/sidecars/k8s}/__init__.py +0 -0
  415. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
  416. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
  417. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
  418. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
  419. {svc_infra-0.1.672/src/svc_infra/obs/templates/sidecars → svc_infra-1.6.1/src/svc_infra/obs/templates/sidecars/railway}/__init__.py +0 -0
  420. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
  421. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/py.typed +0 -0
  422. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/security/headers.py +0 -0
  423. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/__init__.py +0 -0
  424. {svc_infra-0.1.672 → svc_infra-1.6.1}/src/svc_infra/storage/backends/__init__.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,362 @@
1
+ Metadata-Version: 2.3
2
+ Name: svc-infra
3
+ Version: 1.6.1
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 :: 5 - Production/Stable
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
+ # svc-infra
86
+
87
+ **Production-ready FastAPI infrastructure in one import.**
88
+
89
+ [![PyPI](https://img.shields.io/pypi/v/svc-infra.svg)](https://pypi.org/project/svc-infra/)
90
+ [![CI](https://github.com/nfraxlab/svc-infra/actions/workflows/ci.yml/badge.svg)](https://github.com/nfraxlab/svc-infra/actions/workflows/ci.yml)
91
+ [![Python](https://img.shields.io/pypi/pyversions/svc-infra.svg)](https://pypi.org/project/svc-infra/)
92
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
93
+
94
+ ## Overview
95
+
96
+ Stop rebuilding auth, billing, webhooks, and background jobs for every project.
97
+
98
+ ### Key Features
99
+
100
+ - **Auth** - JWT, sessions, OAuth/OIDC, MFA, API keys
101
+ - **Billing** - Usage tracking, subscriptions, invoices, Stripe sync
102
+ - **Database** - PostgreSQL + MongoDB, migrations, inbox/outbox
103
+ - **Jobs** - Background tasks, scheduling, retries, DLQ
104
+ - **Webhooks** - Subscriptions, HMAC signing, delivery retries
105
+ - **Observability** - Prometheus, Grafana dashboards, OTEL
106
+
107
+ ## Why svc-infra?
108
+
109
+ Every FastAPI project needs the same things: authentication, database setup, background jobs, caching, webhooks, billing... You've written this code before. Multiple times.
110
+
111
+ **svc-infra** packages battle-tested infrastructure used in production, so you can focus on your actual product:
112
+
113
+ ```python
114
+ from svc_infra.api.fastapi.ease import easy_service_app
115
+
116
+ app = easy_service_app(name="MyAPI", release="1.0.0")
117
+ # Health checks, CORS, security headers, structured logging
118
+ # Prometheus metrics, OpenTelemetry tracing
119
+ # Request IDs, idempotency middleware
120
+ # That's it. Ship it.
121
+ ```
122
+
123
+ ## Quick Install
124
+
125
+ ```bash
126
+ pip install svc-infra
127
+ ```
128
+
129
+ ## What's Included
130
+
131
+ | Feature | What You Get | One-liner |
132
+ |---------|-------------|-----------|
133
+ | **Auth** | JWT, sessions, OAuth/OIDC, MFA, API keys | `add_auth_users(app)` |
134
+ | **Billing** | Usage tracking, subscriptions, invoices, Stripe sync | `add_billing(app)` |
135
+ | **Database** | PostgreSQL + MongoDB, migrations, inbox/outbox | `add_sql_db(app)` |
136
+ | **Jobs** | Background tasks, scheduling, retries, DLQ | `easy_jobs()` |
137
+ | **Webhooks** | Subscriptions, HMAC signing, delivery retries | `add_webhooks(app)` |
138
+ | **Cache** | Redis/memory, decorators, namespacing | `init_cache()` |
139
+ | **Observability** | Prometheus, Grafana dashboards, OTEL | Built-in |
140
+ | **Storage** | S3, local, memory backends | `add_storage(app)` |
141
+ | **Multi-tenancy** | Tenant isolation, scoped queries | Built-in |
142
+ | **Rate Limiting** | Per-user, per-endpoint, headers | Built-in |
143
+
144
+ ## 30-Second Example
145
+
146
+ Build a complete SaaS backend:
147
+
148
+ ```python
149
+ from fastapi import Depends
150
+ from svc_infra.api.fastapi.ease import easy_service_app
151
+ from svc_infra.api.fastapi.db.sql.add import add_sql_db
152
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
153
+ from svc_infra.jobs.easy import easy_jobs
154
+ from svc_infra.webhooks.fastapi import require_signature
155
+
156
+ # Create app with batteries included
157
+ app = easy_service_app(name="MySaaS", release="1.0.0")
158
+
159
+ # Add infrastructure
160
+ add_sql_db(app) # PostgreSQL with migrations
161
+ add_auth_users(app) # Full auth system
162
+ queue, scheduler = easy_jobs() # Background jobs
163
+
164
+ # Your actual business logic
165
+ @app.post("/api/process")
166
+ async def process_data(user=Depends(current_active_user)):
167
+ job = queue.enqueue("heavy_task", {"user_id": user.id})
168
+ return {"job_id": job.id, "status": "queued"}
169
+
170
+ # Webhook endpoint with signature verification
171
+ @app.post("/webhooks/stripe")
172
+ async def stripe_webhook(payload=Depends(require_signature(lambda: ["whsec_..."]))):
173
+ queue.enqueue("process_payment", payload)
174
+ return {"received": True}
175
+ ```
176
+
177
+ **That's a production-ready API** with auth, database, background jobs, and webhook handling.
178
+
179
+ ## Feature Highlights
180
+
181
+ ### Authentication & Security
182
+
183
+ Full auth system with zero boilerplate:
184
+
185
+ ```python
186
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
187
+
188
+ add_auth_users(app) # Registers /auth/* routes automatically
189
+
190
+ @app.get("/me")
191
+ async def get_profile(user=Depends(current_active_user)):
192
+ return {"email": user.email, "mfa_enabled": user.mfa_enabled}
193
+ ```
194
+
195
+ **Includes:** JWT tokens, session cookies, OAuth/OIDC (Google, GitHub, etc.), MFA/TOTP, password policies, account lockout, key rotation.
196
+
197
+ ### Usage-Based Billing
198
+
199
+ Track usage and generate invoices:
200
+
201
+ ```python
202
+ from svc_infra.billing import BillingService
203
+
204
+ billing = BillingService(session=db, tenant_id="tenant_123")
205
+
206
+ # Record API usage (idempotent)
207
+ billing.record_usage(metric="api_calls", amount=1, idempotency_key="req_abc")
208
+
209
+ # Generate monthly invoice
210
+ invoice = billing.generate_monthly_invoice(
211
+ period_start=datetime(2025, 1, 1),
212
+ period_end=datetime(2025, 2, 1),
213
+ )
214
+ ```
215
+
216
+ **Includes:** Usage events, aggregation, plans & entitlements, subscriptions, invoices, Stripe sync hooks.
217
+
218
+ ### Background Jobs
219
+
220
+ Redis-backed job queue with retries:
221
+
222
+ ```python
223
+ from svc_infra.jobs.easy import easy_jobs
224
+
225
+ queue, scheduler = easy_jobs() # Auto-detects Redis or uses memory
226
+
227
+ # Enqueue work
228
+ queue.enqueue("send_email", {"to": "user@example.com", "template": "welcome"})
229
+
230
+ # Schedule recurring tasks
231
+ scheduler.add("cleanup", interval_seconds=3600, target="myapp.tasks:cleanup")
232
+ ```
233
+
234
+ ```bash
235
+ # Run the worker
236
+ svc-infra jobs run
237
+ ```
238
+
239
+ **Includes:** Visibility timeout, exponential backoff, dead letter queue, interval scheduler, CLI worker.
240
+
241
+ ### Webhooks
242
+
243
+ Send and receive webhooks with proper security:
244
+
245
+ ```python
246
+ from svc_infra.webhooks import add_webhooks, WebhookService
247
+
248
+ add_webhooks(app) # Adds subscription management routes
249
+
250
+ # Publish events
251
+ webhook_service.publish("invoice.paid", {"invoice_id": "inv_123"})
252
+
253
+ # Verify incoming webhooks
254
+ @app.post("/webhooks/external")
255
+ async def receive(payload=Depends(require_signature(lambda: ["secret1", "secret2"]))):
256
+ return {"ok": True}
257
+ ```
258
+
259
+ **Includes:** Subscription store, HMAC-SHA256 signing, delivery retries, idempotent processing.
260
+
261
+ ### Observability
262
+
263
+ Production monitoring out of the box:
264
+
265
+ ```python
266
+ app = easy_service_app(name="MyAPI", release="1.0.0")
267
+ # Prometheus metrics at /metrics
268
+ # Health checks at /healthz, /readyz, /startupz
269
+ # Request tracing with OpenTelemetry
270
+ ```
271
+
272
+ ```bash
273
+ # Generate Grafana dashboards
274
+ svc-infra obs dashboard --service myapi --output ./dashboards/
275
+ ```
276
+
277
+ **Includes:** Prometheus metrics, Grafana dashboard generator, OTEL integration, SLO helpers.
278
+
279
+ ## Configuration
280
+
281
+ Everything is configurable via environment variables:
282
+
283
+ ```bash
284
+ # Database
285
+ SQL_URL=postgresql://user:pass@localhost/mydb
286
+ MONGO_URL=mongodb://localhost:27017
287
+
288
+ # Auth
289
+ AUTH_JWT__SECRET=your-secret-key
290
+ AUTH_SMTP_HOST=smtp.sendgrid.net
291
+
292
+ # Jobs
293
+ JOBS_DRIVER=redis
294
+ REDIS_URL=redis://localhost:6379
295
+
296
+ # Storage
297
+ STORAGE_BACKEND=s3
298
+ STORAGE_S3_BUCKET=my-uploads
299
+
300
+ # Observability
301
+ ENABLE_OBS=true
302
+ METRICS_PATH=/metrics
303
+ ```
304
+
305
+ See the [Environment Reference](docs/environment.md) for all options.
306
+
307
+ ## Documentation
308
+
309
+ | Module | Description | Guide |
310
+ |--------|-------------|-------|
311
+ | **API** | FastAPI bootstrap, middleware, versioning | [docs/api.md](docs/api.md) |
312
+ | **Auth** | Sessions, OAuth/OIDC, MFA, API keys | [docs/auth.md](docs/auth.md) |
313
+ | **Billing** | Usage tracking, subscriptions, invoices | [docs/billing.md](docs/billing.md) |
314
+ | **Database** | SQL + MongoDB, migrations, patterns | [docs/database.md](docs/database.md) |
315
+ | **Jobs** | Background tasks, scheduling | [docs/jobs.md](docs/jobs.md) |
316
+ | **Webhooks** | Publishing, signing, verification | [docs/webhooks.md](docs/webhooks.md) |
317
+ | **Cache** | Redis/memory caching, TTL helpers | [docs/cache.md](docs/cache.md) |
318
+ | **Storage** | S3, local, memory file storage | [docs/storage.md](docs/storage.md) |
319
+ | **Observability** | Metrics, tracing, dashboards | [docs/observability.md](docs/observability.md) |
320
+ | **Security** | Password policy, headers, MFA | [docs/security.md](docs/security.md) |
321
+ | **Tenancy** | Multi-tenant isolation | [docs/tenancy.md](docs/tenancy.md) |
322
+ | **CLI** | Command-line tools | [docs/cli.md](docs/cli.md) |
323
+
324
+ ## Running the Example
325
+
326
+ See all features working together:
327
+
328
+ ```bash
329
+ git clone https://github.com/nfraxlab/svc-infra.git
330
+ cd svc-infra
331
+
332
+ # Setup and run
333
+ make setup-template # Creates DB, runs migrations
334
+ make run-template # Starts at http://localhost:8001
335
+ ```
336
+
337
+ Visit http://localhost:8001/docs to explore the API.
338
+
339
+ ## Related Packages
340
+
341
+ svc-infra is part of the **nfrax** infrastructure suite:
342
+
343
+ | Package | Purpose |
344
+ |---------|---------|
345
+ | **[svc-infra](https://github.com/nfraxlab/svc-infra)** | Backend infrastructure (auth, billing, jobs, webhooks) |
346
+ | **[ai-infra](https://github.com/nfraxlab/ai-infra)** | AI/LLM infrastructure (agents, tools, RAG, MCP) |
347
+ | **[fin-infra](https://github.com/nfraxlab/fin-infra)** | Financial infrastructure (banking, portfolio, insights) |
348
+
349
+ ## License
350
+
351
+ MIT License - use it for anything.
352
+
353
+ ---
354
+
355
+ <div align="center">
356
+
357
+ **Built by [nfraxlab](https://github.com/nfraxlab)**
358
+
359
+ [Star us on GitHub](https://github.com/nfraxlab/svc-infra) · [View on PyPI](https://pypi.org/project/svc-infra/)
360
+
361
+ </div>
362
+
@@ -0,0 +1,277 @@
1
+ # svc-infra
2
+
3
+ **Production-ready FastAPI infrastructure in one import.**
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/svc-infra.svg)](https://pypi.org/project/svc-infra/)
6
+ [![CI](https://github.com/nfraxlab/svc-infra/actions/workflows/ci.yml/badge.svg)](https://github.com/nfraxlab/svc-infra/actions/workflows/ci.yml)
7
+ [![Python](https://img.shields.io/pypi/pyversions/svc-infra.svg)](https://pypi.org/project/svc-infra/)
8
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
+
10
+ ## Overview
11
+
12
+ Stop rebuilding auth, billing, webhooks, and background jobs for every project.
13
+
14
+ ### Key Features
15
+
16
+ - **Auth** - JWT, sessions, OAuth/OIDC, MFA, API keys
17
+ - **Billing** - Usage tracking, subscriptions, invoices, Stripe sync
18
+ - **Database** - PostgreSQL + MongoDB, migrations, inbox/outbox
19
+ - **Jobs** - Background tasks, scheduling, retries, DLQ
20
+ - **Webhooks** - Subscriptions, HMAC signing, delivery retries
21
+ - **Observability** - Prometheus, Grafana dashboards, OTEL
22
+
23
+ ## Why svc-infra?
24
+
25
+ Every FastAPI project needs the same things: authentication, database setup, background jobs, caching, webhooks, billing... You've written this code before. Multiple times.
26
+
27
+ **svc-infra** packages battle-tested infrastructure used in production, so you can focus on your actual product:
28
+
29
+ ```python
30
+ from svc_infra.api.fastapi.ease import easy_service_app
31
+
32
+ app = easy_service_app(name="MyAPI", release="1.0.0")
33
+ # Health checks, CORS, security headers, structured logging
34
+ # Prometheus metrics, OpenTelemetry tracing
35
+ # Request IDs, idempotency middleware
36
+ # That's it. Ship it.
37
+ ```
38
+
39
+ ## Quick Install
40
+
41
+ ```bash
42
+ pip install svc-infra
43
+ ```
44
+
45
+ ## What's Included
46
+
47
+ | Feature | What You Get | One-liner |
48
+ |---------|-------------|-----------|
49
+ | **Auth** | JWT, sessions, OAuth/OIDC, MFA, API keys | `add_auth_users(app)` |
50
+ | **Billing** | Usage tracking, subscriptions, invoices, Stripe sync | `add_billing(app)` |
51
+ | **Database** | PostgreSQL + MongoDB, migrations, inbox/outbox | `add_sql_db(app)` |
52
+ | **Jobs** | Background tasks, scheduling, retries, DLQ | `easy_jobs()` |
53
+ | **Webhooks** | Subscriptions, HMAC signing, delivery retries | `add_webhooks(app)` |
54
+ | **Cache** | Redis/memory, decorators, namespacing | `init_cache()` |
55
+ | **Observability** | Prometheus, Grafana dashboards, OTEL | Built-in |
56
+ | **Storage** | S3, local, memory backends | `add_storage(app)` |
57
+ | **Multi-tenancy** | Tenant isolation, scoped queries | Built-in |
58
+ | **Rate Limiting** | Per-user, per-endpoint, headers | Built-in |
59
+
60
+ ## 30-Second Example
61
+
62
+ Build a complete SaaS backend:
63
+
64
+ ```python
65
+ from fastapi import Depends
66
+ from svc_infra.api.fastapi.ease import easy_service_app
67
+ from svc_infra.api.fastapi.db.sql.add import add_sql_db
68
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
69
+ from svc_infra.jobs.easy import easy_jobs
70
+ from svc_infra.webhooks.fastapi import require_signature
71
+
72
+ # Create app with batteries included
73
+ app = easy_service_app(name="MySaaS", release="1.0.0")
74
+
75
+ # Add infrastructure
76
+ add_sql_db(app) # PostgreSQL with migrations
77
+ add_auth_users(app) # Full auth system
78
+ queue, scheduler = easy_jobs() # Background jobs
79
+
80
+ # Your actual business logic
81
+ @app.post("/api/process")
82
+ async def process_data(user=Depends(current_active_user)):
83
+ job = queue.enqueue("heavy_task", {"user_id": user.id})
84
+ return {"job_id": job.id, "status": "queued"}
85
+
86
+ # Webhook endpoint with signature verification
87
+ @app.post("/webhooks/stripe")
88
+ async def stripe_webhook(payload=Depends(require_signature(lambda: ["whsec_..."]))):
89
+ queue.enqueue("process_payment", payload)
90
+ return {"received": True}
91
+ ```
92
+
93
+ **That's a production-ready API** with auth, database, background jobs, and webhook handling.
94
+
95
+ ## Feature Highlights
96
+
97
+ ### Authentication & Security
98
+
99
+ Full auth system with zero boilerplate:
100
+
101
+ ```python
102
+ from svc_infra.api.fastapi.auth import add_auth_users, current_active_user
103
+
104
+ add_auth_users(app) # Registers /auth/* routes automatically
105
+
106
+ @app.get("/me")
107
+ async def get_profile(user=Depends(current_active_user)):
108
+ return {"email": user.email, "mfa_enabled": user.mfa_enabled}
109
+ ```
110
+
111
+ **Includes:** JWT tokens, session cookies, OAuth/OIDC (Google, GitHub, etc.), MFA/TOTP, password policies, account lockout, key rotation.
112
+
113
+ ### Usage-Based Billing
114
+
115
+ Track usage and generate invoices:
116
+
117
+ ```python
118
+ from svc_infra.billing import BillingService
119
+
120
+ billing = BillingService(session=db, tenant_id="tenant_123")
121
+
122
+ # Record API usage (idempotent)
123
+ billing.record_usage(metric="api_calls", amount=1, idempotency_key="req_abc")
124
+
125
+ # Generate monthly invoice
126
+ invoice = billing.generate_monthly_invoice(
127
+ period_start=datetime(2025, 1, 1),
128
+ period_end=datetime(2025, 2, 1),
129
+ )
130
+ ```
131
+
132
+ **Includes:** Usage events, aggregation, plans & entitlements, subscriptions, invoices, Stripe sync hooks.
133
+
134
+ ### Background Jobs
135
+
136
+ Redis-backed job queue with retries:
137
+
138
+ ```python
139
+ from svc_infra.jobs.easy import easy_jobs
140
+
141
+ queue, scheduler = easy_jobs() # Auto-detects Redis or uses memory
142
+
143
+ # Enqueue work
144
+ queue.enqueue("send_email", {"to": "user@example.com", "template": "welcome"})
145
+
146
+ # Schedule recurring tasks
147
+ scheduler.add("cleanup", interval_seconds=3600, target="myapp.tasks:cleanup")
148
+ ```
149
+
150
+ ```bash
151
+ # Run the worker
152
+ svc-infra jobs run
153
+ ```
154
+
155
+ **Includes:** Visibility timeout, exponential backoff, dead letter queue, interval scheduler, CLI worker.
156
+
157
+ ### Webhooks
158
+
159
+ Send and receive webhooks with proper security:
160
+
161
+ ```python
162
+ from svc_infra.webhooks import add_webhooks, WebhookService
163
+
164
+ add_webhooks(app) # Adds subscription management routes
165
+
166
+ # Publish events
167
+ webhook_service.publish("invoice.paid", {"invoice_id": "inv_123"})
168
+
169
+ # Verify incoming webhooks
170
+ @app.post("/webhooks/external")
171
+ async def receive(payload=Depends(require_signature(lambda: ["secret1", "secret2"]))):
172
+ return {"ok": True}
173
+ ```
174
+
175
+ **Includes:** Subscription store, HMAC-SHA256 signing, delivery retries, idempotent processing.
176
+
177
+ ### Observability
178
+
179
+ Production monitoring out of the box:
180
+
181
+ ```python
182
+ app = easy_service_app(name="MyAPI", release="1.0.0")
183
+ # Prometheus metrics at /metrics
184
+ # Health checks at /healthz, /readyz, /startupz
185
+ # Request tracing with OpenTelemetry
186
+ ```
187
+
188
+ ```bash
189
+ # Generate Grafana dashboards
190
+ svc-infra obs dashboard --service myapi --output ./dashboards/
191
+ ```
192
+
193
+ **Includes:** Prometheus metrics, Grafana dashboard generator, OTEL integration, SLO helpers.
194
+
195
+ ## Configuration
196
+
197
+ Everything is configurable via environment variables:
198
+
199
+ ```bash
200
+ # Database
201
+ SQL_URL=postgresql://user:pass@localhost/mydb
202
+ MONGO_URL=mongodb://localhost:27017
203
+
204
+ # Auth
205
+ AUTH_JWT__SECRET=your-secret-key
206
+ AUTH_SMTP_HOST=smtp.sendgrid.net
207
+
208
+ # Jobs
209
+ JOBS_DRIVER=redis
210
+ REDIS_URL=redis://localhost:6379
211
+
212
+ # Storage
213
+ STORAGE_BACKEND=s3
214
+ STORAGE_S3_BUCKET=my-uploads
215
+
216
+ # Observability
217
+ ENABLE_OBS=true
218
+ METRICS_PATH=/metrics
219
+ ```
220
+
221
+ See the [Environment Reference](docs/environment.md) for all options.
222
+
223
+ ## Documentation
224
+
225
+ | Module | Description | Guide |
226
+ |--------|-------------|-------|
227
+ | **API** | FastAPI bootstrap, middleware, versioning | [docs/api.md](docs/api.md) |
228
+ | **Auth** | Sessions, OAuth/OIDC, MFA, API keys | [docs/auth.md](docs/auth.md) |
229
+ | **Billing** | Usage tracking, subscriptions, invoices | [docs/billing.md](docs/billing.md) |
230
+ | **Database** | SQL + MongoDB, migrations, patterns | [docs/database.md](docs/database.md) |
231
+ | **Jobs** | Background tasks, scheduling | [docs/jobs.md](docs/jobs.md) |
232
+ | **Webhooks** | Publishing, signing, verification | [docs/webhooks.md](docs/webhooks.md) |
233
+ | **Cache** | Redis/memory caching, TTL helpers | [docs/cache.md](docs/cache.md) |
234
+ | **Storage** | S3, local, memory file storage | [docs/storage.md](docs/storage.md) |
235
+ | **Observability** | Metrics, tracing, dashboards | [docs/observability.md](docs/observability.md) |
236
+ | **Security** | Password policy, headers, MFA | [docs/security.md](docs/security.md) |
237
+ | **Tenancy** | Multi-tenant isolation | [docs/tenancy.md](docs/tenancy.md) |
238
+ | **CLI** | Command-line tools | [docs/cli.md](docs/cli.md) |
239
+
240
+ ## Running the Example
241
+
242
+ See all features working together:
243
+
244
+ ```bash
245
+ git clone https://github.com/nfraxlab/svc-infra.git
246
+ cd svc-infra
247
+
248
+ # Setup and run
249
+ make setup-template # Creates DB, runs migrations
250
+ make run-template # Starts at http://localhost:8001
251
+ ```
252
+
253
+ Visit http://localhost:8001/docs to explore the API.
254
+
255
+ ## Related Packages
256
+
257
+ svc-infra is part of the **nfrax** infrastructure suite:
258
+
259
+ | Package | Purpose |
260
+ |---------|---------|
261
+ | **[svc-infra](https://github.com/nfraxlab/svc-infra)** | Backend infrastructure (auth, billing, jobs, webhooks) |
262
+ | **[ai-infra](https://github.com/nfraxlab/ai-infra)** | AI/LLM infrastructure (agents, tools, RAG, MCP) |
263
+ | **[fin-infra](https://github.com/nfraxlab/fin-infra)** | Financial infrastructure (banking, portfolio, insights) |
264
+
265
+ ## License
266
+
267
+ MIT License - use it for anything.
268
+
269
+ ---
270
+
271
+ <div align="center">
272
+
273
+ **Built by [nfraxlab](https://github.com/nfraxlab)**
274
+
275
+ [Star us on GitHub](https://github.com/nfraxlab/svc-infra) · [View on PyPI](https://pypi.org/project/svc-infra/)
276
+
277
+ </div>