svc-infra 0.1.601__tar.gz → 0.1.602__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 (283) hide show
  1. {svc_infra-0.1.601 → svc_infra-0.1.602}/PKG-INFO +1 -1
  2. {svc_infra-0.1.601 → svc_infra-0.1.602}/pyproject.toml +1 -1
  3. svc_infra-0.1.602/src/svc_infra/api/fastapi/docs/add.py +60 -0
  4. svc_infra-0.1.602/src/svc_infra/api/fastapi/ops/add.py +65 -0
  5. svc_infra-0.1.602/src/svc_infra/data/add.py +59 -0
  6. svc_infra-0.1.602/src/svc_infra/dx/add.py +63 -0
  7. {svc_infra-0.1.601 → svc_infra-0.1.602}/README.md +0 -0
  8. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/__init__.py +0 -0
  9. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/README.md +0 -0
  10. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/__init__.py +0 -0
  11. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/alembic.py +0 -0
  12. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/models.py +0 -0
  13. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/provider/__init__.py +0 -0
  14. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/provider/aiydan.py +0 -0
  15. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/provider/base.py +0 -0
  16. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/provider/registry.py +0 -0
  17. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/provider/stripe.py +0 -0
  18. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/schemas.py +0 -0
  19. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/service.py +0 -0
  20. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/apf_payments/settings.py +0 -0
  21. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/__init__.py +0 -0
  22. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/__init__.py +0 -0
  23. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/apf_payments/__init__.py +0 -0
  24. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/apf_payments/router.py +0 -0
  25. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/apf_payments/setup.py +0 -0
  26. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/__init__.py +0 -0
  27. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/_cookies.py +0 -0
  28. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/add.py +0 -0
  29. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/gaurd.py +0 -0
  30. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/__init__.py +0 -0
  31. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/models.py +0 -0
  32. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +0 -0
  33. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/router.py +0 -0
  34. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/security.py +0 -0
  35. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/utils.py +0 -0
  36. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/mfa/verify.py +0 -0
  37. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/policy.py +0 -0
  38. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/providers.py +0 -0
  39. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/routers/__init__.py +0 -0
  40. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
  41. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +0 -0
  42. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +0 -0
  43. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/routers/session_router.py +0 -0
  44. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/security.py +0 -0
  45. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/sender.py +0 -0
  46. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/settings.py +0 -0
  47. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/auth/state.py +0 -0
  48. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/cache/__init__.py +0 -0
  49. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/cache/add.py +0 -0
  50. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/__init__.py +0 -0
  51. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/http.py +0 -0
  52. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -0
  53. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/nosql/mongo/__init__.py +0 -0
  54. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +0 -0
  55. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +0 -0
  56. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
  57. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/README.md +0 -0
  58. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/__init__.py +0 -0
  59. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/add.py +0 -0
  60. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/crud_router.py +0 -0
  61. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/health.py +0 -0
  62. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/session.py +0 -0
  63. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/db/sql/users.py +0 -0
  64. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +0 -0
  65. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/docs/__init__.py +0 -0
  66. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/docs/landing.py +0 -0
  67. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/docs/scoped.py +0 -0
  68. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/__init__.py +0 -0
  69. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/dualize.py +0 -0
  70. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/protected.py +0 -0
  71. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/public.py +0 -0
  72. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/router.py +0 -0
  73. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
  74. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/dx.py +0 -0
  75. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/ease.py +0 -0
  76. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/http/__init__.py +0 -0
  77. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/http/concurrency.py +0 -0
  78. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/http/conditional.py +0 -0
  79. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
  80. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/__init__.py +0 -0
  81. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/debug.py +0 -0
  82. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/errors/__init__.py +0 -0
  83. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +0 -0
  84. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +0 -0
  85. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +0 -0
  86. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -0
  87. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +0 -0
  88. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +0 -0
  89. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -0
  90. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +0 -0
  91. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/request_id.py +0 -0
  92. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +0 -0
  93. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/__init__.py +0 -0
  94. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/apply.py +0 -0
  95. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/conventions.py +0 -0
  96. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/models.py +0 -0
  97. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/mutators.py +0 -0
  98. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/pipeline.py +0 -0
  99. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/responses.py +0 -0
  100. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/openapi/security.py +0 -0
  101. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/pagination.py +0 -0
  102. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/paths/__init__.py +0 -0
  103. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
  104. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
  105. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
  106. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/paths/user.py +0 -0
  107. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/routers/__init__.py +0 -0
  108. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
  109. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/setup.py +0 -0
  110. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/tenancy/add.py +0 -0
  111. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/api/fastapi/tenancy/context.py +0 -0
  112. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/README.md +0 -0
  113. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/__init__.py +0 -0
  114. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/env.py +0 -0
  115. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/logging/__init__.py +0 -0
  116. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/logging/add.py +0 -0
  117. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/logging/filter.py +0 -0
  118. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/logging/formats.py +0 -0
  119. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/app/root.py +0 -0
  120. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/README.md +0 -0
  121. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/__init__.py +0 -0
  122. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/backend.py +0 -0
  123. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/decorators.py +0 -0
  124. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/demo.py +0 -0
  125. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/keys.py +0 -0
  126. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/recache.py +0 -0
  127. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/resources.py +0 -0
  128. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/tags.py +0 -0
  129. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/ttl.py +0 -0
  130. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cache/utils.py +0 -0
  131. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/__init__.py +0 -0
  132. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/__main__.py +0 -0
  133. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/__init__.py +0 -0
  134. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/__init__.py +0 -0
  135. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/nosql/__init__.py +0 -0
  136. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +0 -0
  137. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/nosql/mongo/__init__.py +0 -0
  138. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +0 -0
  139. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +0 -0
  140. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/sql/__init__.py +0 -0
  141. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +0 -0
  142. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +0 -0
  143. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +0 -0
  144. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/help.py +0 -0
  145. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
  146. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +0 -0
  147. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/obs/__init__.py +0 -0
  148. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/cmds/obs/obs_cmds.py +0 -0
  149. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/foundation/__init__.py +0 -0
  150. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/foundation/runner.py +0 -0
  151. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/cli/foundation/typer_bootstrap.py +0 -0
  152. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/__init__.py +0 -0
  153. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/crud_schema.py +0 -0
  154. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/inbox.py +0 -0
  155. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/__init__.py +0 -0
  156. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/base.py +0 -0
  157. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/constants.py +0 -0
  158. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/core.py +0 -0
  159. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/indexes.py +0 -0
  160. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/management.py +0 -0
  161. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/README.md +0 -0
  162. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/__init__.py +0 -0
  163. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/client.py +0 -0
  164. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/settings.py +0 -0
  165. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/templates/__init__.py +0 -0
  166. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
  167. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
  168. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
  169. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/repository.py +0 -0
  170. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/resource.py +0 -0
  171. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/scaffold.py +0 -0
  172. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/service.py +0 -0
  173. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/service_with_hooks.py +0 -0
  174. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/types.py +0 -0
  175. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/nosql/utils.py +0 -0
  176. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/outbox.py +0 -0
  177. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/README.md +0 -0
  178. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/__init__.py +0 -0
  179. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/apikey.py +0 -0
  180. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/authref.py +0 -0
  181. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/base.py +0 -0
  182. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/constants.py +0 -0
  183. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/core.py +0 -0
  184. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/management.py +0 -0
  185. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/repository.py +0 -0
  186. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/resource.py +0 -0
  187. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/scaffold.py +0 -0
  188. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/service.py +0 -0
  189. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/service_with_hooks.py +0 -0
  190. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/__init__.py +0 -0
  191. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/models_schemas/__init__.py +0 -0
  192. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +0 -0
  193. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
  194. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
  195. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
  196. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/setup/__init__.py +0 -0
  197. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
  198. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +0 -0
  199. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +0 -0
  200. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
  201. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/tenant.py +0 -0
  202. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/types.py +0 -0
  203. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/uniq.py +0 -0
  204. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/uniq_hooks.py +0 -0
  205. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/utils.py +0 -0
  206. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/sql/versioning.py +0 -0
  207. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/db/utils.py +0 -0
  208. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/builtins/outbox_processor.py +0 -0
  209. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/builtins/webhook_delivery.py +0 -0
  210. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/easy.py +0 -0
  211. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/loader.py +0 -0
  212. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/queue.py +0 -0
  213. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/redis_queue.py +0 -0
  214. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/scheduler.py +0 -0
  215. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/jobs/worker.py +0 -0
  216. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/mcp/__init__.py +0 -0
  217. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/mcp/svc_infra_mcp.py +0 -0
  218. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/README.md +0 -0
  219. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/__init__.py +0 -0
  220. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/add.py +0 -0
  221. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/cloud_dash.py +0 -0
  222. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics/__init__.py +0 -0
  223. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics/asgi.py +0 -0
  224. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics/base.py +0 -0
  225. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics/http.py +0 -0
  226. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics/sqlalchemy.py +0 -0
  227. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/metrics.py +0 -0
  228. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/__init__.py +0 -0
  229. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/compose_cloud/__init__.py +0 -0
  230. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/compose_cloud/templates/__init__.py +0 -0
  231. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
  232. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
  233. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/__init__.py +0 -0
  234. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
  235. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
  236. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
  237. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
  238. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
  239. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/dashboards/__init__.py +0 -0
  240. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/__init__.py +0 -0
  241. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
  242. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
  243. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/provisioning/__init__.py +0 -0
  244. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
  245. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
  246. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/settings.py +0 -0
  247. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
  248. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
  249. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/__init__.py +0 -0
  250. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/compose/__init__.py +0 -0
  251. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
  252. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
  253. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
  254. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
  255. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
  256. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
  257. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
  258. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
  259. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
  260. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
  261. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
  262. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
  263. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/py.typed +0 -0
  264. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/add.py +0 -0
  265. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/audit.py +0 -0
  266. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/audit_service.py +0 -0
  267. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/headers.py +0 -0
  268. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/hibp.py +0 -0
  269. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/jwt_rotation.py +0 -0
  270. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/lockout.py +0 -0
  271. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/models.py +0 -0
  272. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/org_invites.py +0 -0
  273. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/passwords.py +0 -0
  274. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/permissions.py +0 -0
  275. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/session.py +0 -0
  276. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/security/signed_cookies.py +0 -0
  277. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/utils.py +0 -0
  278. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/__init__.py +0 -0
  279. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/add.py +0 -0
  280. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/fastapi.py +0 -0
  281. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/router.py +0 -0
  282. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/service.py +0 -0
  283. {svc_infra-0.1.601 → svc_infra-0.1.602}/src/svc_infra/webhooks/signing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: svc-infra
3
- Version: 0.1.601
3
+ Version: 0.1.602
4
4
  Summary: Infrastructure for building and deploying prod-ready services
5
5
  License: MIT
6
6
  Keywords: fastapi,sqlalchemy,alembic,auth,infra,async,pydantic
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "svc-infra"
3
- version = "0.1.601"
3
+ version = "0.1.602"
4
4
  description = "Infrastructure for building and deploying prod-ready services"
5
5
  authors = ["Ali Khatami <aliikhatami94@gmail.com>"]
6
6
  license = "MIT"
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ from fastapi import FastAPI
8
+
9
+
10
+ def add_docs(
11
+ app: FastAPI,
12
+ *,
13
+ redoc_url: str = "/redoc",
14
+ swagger_url: str = "/docs",
15
+ openapi_url: str = "/openapi.json",
16
+ export_openapi_to: Optional[str] = None,
17
+ ) -> None:
18
+ """Enable docs endpoints and optionally export OpenAPI schema to disk on startup."""
19
+ # Configure FastAPI docs URLs
20
+ app.docs_url = swagger_url
21
+ app.redoc_url = redoc_url
22
+ app.openapi_url = openapi_url
23
+
24
+ if export_openapi_to:
25
+ export_path = Path(export_openapi_to)
26
+
27
+ @app.on_event("startup")
28
+ async def _export_spec() -> None: # noqa: ANN202
29
+ spec = app.openapi()
30
+ export_path.parent.mkdir(parents=True, exist_ok=True)
31
+ export_path.write_text(json.dumps(spec, indent=2))
32
+
33
+
34
+ def add_sdk_generation_stub(
35
+ app: FastAPI,
36
+ *,
37
+ on_generate: Optional[callable] = None,
38
+ openapi_path: str = "/openapi.json",
39
+ ) -> None:
40
+ """Hook to add an SDK generation stub.
41
+
42
+ Provide `on_generate()` to run generation (e.g., openapi-generator). This is a stub only; we
43
+ don't ship a hard dependency. If `on_generate` is provided, we expose `/_docs/generate-sdk`.
44
+ """
45
+ from svc_infra.api.fastapi.dual.public import public_router
46
+
47
+ if not on_generate:
48
+ return
49
+
50
+ router = public_router(prefix="/_docs", include_in_schema=False)
51
+
52
+ @router.post("/generate-sdk")
53
+ async def _generate() -> dict: # noqa: ANN201
54
+ on_generate()
55
+ return {"status": "ok"}
56
+
57
+ app.include_router(router)
58
+
59
+
60
+ __all__ = ["add_docs", "add_sdk_generation_stub"]
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Callable
5
+
6
+ from fastapi import FastAPI, HTTPException, Request
7
+ from starlette.responses import JSONResponse
8
+
9
+
10
+ def add_probes(
11
+ app: FastAPI,
12
+ *,
13
+ prefix: str = "/_ops",
14
+ include_in_schema: bool = False,
15
+ ) -> None:
16
+ """Mount basic liveness/readiness/startup probes under prefix."""
17
+ from svc_infra.api.fastapi.dual.public import public_router
18
+
19
+ router = public_router(prefix=prefix, tags=["ops"], include_in_schema=include_in_schema)
20
+
21
+ @router.get("/live")
22
+ async def live() -> JSONResponse: # noqa: D401, ANN201
23
+ return JSONResponse({"status": "ok"})
24
+
25
+ @router.get("/ready")
26
+ async def ready() -> JSONResponse: # noqa: D401, ANN201
27
+ # In the future, add checks (DB ping, cache ping) via DI hooks.
28
+ return JSONResponse({"status": "ok"})
29
+
30
+ @router.get("/startup")
31
+ async def startup_probe() -> JSONResponse: # noqa: D401, ANN201
32
+ return JSONResponse({"status": "ok"})
33
+
34
+ app.include_router(router)
35
+
36
+
37
+ def add_maintenance_mode(app: FastAPI, *, env_var: str = "MAINTENANCE_MODE") -> None:
38
+ """Enable a simple maintenance gate controlled by an env var.
39
+
40
+ When MAINTENANCE_MODE is truthy, all non-GET requests return 503.
41
+ """
42
+
43
+ @app.middleware("http")
44
+ async def _maintenance_gate(request: Request, call_next): # noqa: ANN001, ANN202
45
+ flag = str(os.getenv(env_var, "")).lower() in {"1", "true", "yes", "on"}
46
+ if flag and request.method not in {"GET", "HEAD", "OPTIONS"}:
47
+ return JSONResponse({"detail": "maintenance"}, status_code=503)
48
+ return await call_next(request)
49
+
50
+
51
+ def circuit_breaker_dependency(limit: int = 100, window_seconds: int = 60) -> Callable:
52
+ """Return a dependency that can trip rejective errors based on external metrics.
53
+
54
+ This is a placeholder; callers can swap with a provider that tracks failures and opens the
55
+ breaker. Here, we read an env var to simulate an open breaker.
56
+ """
57
+
58
+ async def _dep(_: Request) -> None: # noqa: D401, ANN202
59
+ if str(os.getenv("CIRCUIT_OPEN", "")).lower() in {"1", "true", "yes", "on"}:
60
+ raise HTTPException(status_code=503, detail="circuit open")
61
+
62
+ return _dep
63
+
64
+
65
+ __all__ = ["add_probes", "add_maintenance_mode", "circuit_breaker_dependency"]
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Callable, Iterable, Optional
4
+
5
+ from fastapi import FastAPI
6
+
7
+ from svc_infra.cli.cmds.db.sql.alembic_cmds import cmd_setup_and_migrate
8
+
9
+
10
+ def add_data_lifecycle(
11
+ app: FastAPI,
12
+ *,
13
+ auto_migrate: bool = True,
14
+ database_url: str | None = None,
15
+ discover_packages: Optional[list[str]] = None,
16
+ with_payments: bool | None = None,
17
+ on_load_fixtures: Optional[Callable[[], None]] = None,
18
+ retention_jobs: Optional[Iterable[Callable[[], None]]] = None,
19
+ erasure_job: Optional[Callable[[str], None]] = None,
20
+ ) -> None:
21
+ """
22
+ Wire data lifecycle conveniences:
23
+
24
+ - auto_migrate: run end-to-end Alembic setup-and-migrate on startup (idempotent).
25
+ - on_load_fixtures: optional callback to load reference/fixture data once at startup.
26
+ - retention_jobs: optional list of callables to register purge tasks (scheduler integration is external).
27
+ - erasure_job: optional callable to trigger a GDPR erasure workflow for a given principal ID.
28
+
29
+ This helper is intentionally minimal: it coordinates existing building blocks
30
+ and offers extension points. Jobs should be scheduled using svc_infra.jobs helpers.
31
+ """
32
+
33
+ @app.on_event("startup")
34
+ async def _data_lifecycle_startup() -> None: # noqa: D401, ANN202
35
+ if auto_migrate:
36
+ # Use existing CLI function to perform end-to-end setup and migrate.
37
+ cmd_setup_and_migrate(
38
+ database_url=database_url,
39
+ overwrite_scaffold=False,
40
+ create_db_if_missing=True,
41
+ create_followup_revision=True,
42
+ initial_message="initial schema",
43
+ followup_message="autogen",
44
+ discover_packages=discover_packages,
45
+ with_payments=with_payments,
46
+ )
47
+
48
+ if on_load_fixtures:
49
+ # Run user-provided fixture loader (idempotent expected).
50
+ on_load_fixtures()
51
+
52
+ # Store optional jobs on app.state for external schedulers to discover/register.
53
+ if retention_jobs is not None:
54
+ app.state.data_retention_jobs = list(retention_jobs)
55
+ if erasure_job is not None:
56
+ app.state.data_erasure_job = erasure_job
57
+
58
+
59
+ __all__ = ["add_data_lifecycle"]
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ def write_ci_workflow(
7
+ *,
8
+ target_dir: str | Path,
9
+ name: str = "ci.yml",
10
+ python_version: str = "3.12",
11
+ ) -> Path:
12
+ """Write a minimal CI workflow file (GitHub Actions) with tests/lint/type steps."""
13
+ p = Path(target_dir) / ".github" / "workflows" / name
14
+ p.parent.mkdir(parents=True, exist_ok=True)
15
+ content = f"""
16
+ name: CI
17
+
18
+ on:
19
+ push:
20
+ branches: [ main ]
21
+ pull_request:
22
+
23
+ jobs:
24
+ build:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: actions/setup-python@v5
29
+ with:
30
+ python-version: '{python_version}'
31
+ - name: Install Poetry
32
+ run: pipx install poetry
33
+ - name: Install deps
34
+ run: poetry install
35
+ - name: Lint
36
+ run: poetry run flake8 --select=E,F
37
+ - name: Typecheck
38
+ run: poetry run mypy src
39
+ - name: Tests
40
+ run: poetry run pytest -q -W error
41
+ """
42
+ p.write_text(content.strip() + "\n")
43
+ return p
44
+
45
+
46
+ def write_openapi_lint_config(*, target_dir: str | Path, name: str = ".redocly.yaml") -> Path:
47
+ """Write a minimal OpenAPI lint config placeholder (Redocly)."""
48
+ p = Path(target_dir) / name
49
+ content = """
50
+ apis:
51
+ main:
52
+ root: openapi.json
53
+
54
+ rules:
55
+ operation-operationId: warn
56
+ no-unused-components: warn
57
+ security-defined: off
58
+ """
59
+ p.write_text(content.strip() + "\n")
60
+ return p
61
+
62
+
63
+ __all__ = ["write_ci_workflow", "write_openapi_lint_config"]
File without changes