svc-infra 0.1.622__tar.gz → 0.1.624__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.
- {svc_infra-0.1.622 → svc_infra-0.1.624}/PKG-INFO +26 -17
- {svc_infra-0.1.622 → svc_infra-0.1.624}/README.md +25 -16
- {svc_infra-0.1.622 → svc_infra-0.1.624}/pyproject.toml +2 -2
- svc_infra-0.1.624/src/svc_infra/cli/cmds/docs/docs_cmds.py +189 -0
- svc_infra-0.1.624/src/svc_infra/docs/getting-started.md +63 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/mcp/svc_infra_mcp.py +21 -1
- svc_infra-0.1.622/src/svc_infra/cli/cmds/docs/docs_cmds.py +0 -225
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/alembic.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/models.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/provider/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/provider/aiydan.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/provider/base.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/provider/registry.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/provider/stripe.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/schemas.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/apf_payments/settings.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/apf_payments/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/apf_payments/router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/apf_payments/setup.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/_cookies.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/gaurd.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/models.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/security.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/mfa/verify.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/policy.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/providers.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/routers/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/routers/session_router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/security.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/sender.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/settings.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/auth/state.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/cache/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/cache/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/http.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/crud_router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/health.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/session.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/db/sql/users.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/docs/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/docs/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/docs/landing.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/docs/scoped.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/dualize.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/protected.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/public.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/dx.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/ease.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/http/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/http/concurrency.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/http/conditional.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/debug.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/errors/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/request_id.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/apply.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/conventions.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/models.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/mutators.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/pipeline.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/responses.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/openapi/security.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/ops/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/pagination.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/paths/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/paths/user.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/routers/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/setup.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/tenancy/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/api/fastapi/tenancy/context.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/env.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/logging/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/logging/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/logging/filter.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/logging/formats.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/app/root.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/billing/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/billing/models.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/billing/service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/bundled_docs/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/bundled_docs/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/bundled_docs/getting-started.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/backend.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/decorators.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/demo.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/keys.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/recache.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/resources.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/tags.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/ttl.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cache/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/__main__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/sql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/dx/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/dx/dx_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/help.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/obs/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/obs/obs_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/sdk/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/cmds/sdk/sdk_cmds.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/foundation/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/foundation/runner.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/cli/foundation/typer_bootstrap.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/data/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/data/backup.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/data/erasure.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/data/fixtures.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/data/retention.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/crud_schema.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/inbox.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/base.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/constants.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/core.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/indexes.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/management.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/client.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/settings.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/templates/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/repository.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/resource.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/scaffold.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/service_with_hooks.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/types.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/nosql/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/outbox.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/apikey.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/authref.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/base.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/constants.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/core.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/management.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/repository.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/resource.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/scaffold.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/service_with_hooks.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/models_schemas/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/setup/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/tenant.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/types.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/uniq.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/uniq_hooks.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/sql/versioning.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/db/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/acceptance-matrix.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/acceptance.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0002-background-jobs-and-scheduling.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0003-webhooks-framework.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0004-tenancy-model.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0005-data-lifecycle.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0006-ops-slos-and-metrics.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0007-docs-and-sdks.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0008-billing-primitives.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/adr/0009-acceptance-harness.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/api.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/auth.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/cache.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/cli.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/contributing.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/data-lifecycle.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/database.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/docs-and-sdks.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/environment.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/idempotency.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/jobs.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/observability.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/ops.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/rate-limiting.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/repo-review.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/security.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/tenancy.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624/src/svc_infra}/docs/webhooks.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/dx/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/dx/changelog.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/dx/checks.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/builtins/outbox_processor.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/builtins/webhook_delivery.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/easy.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/loader.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/queue.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/redis_queue.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/scheduler.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/jobs/worker.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/mcp/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/cloud_dash.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/grafana/dashboards/http-overview.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics/asgi.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics/base.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics/http.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics/sqlalchemy.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/metrics.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/compose_cloud/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/compose_cloud/templates/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/dashboards/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/provisioning/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/settings.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/compose/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/py.typed +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/audit.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/audit_service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/headers.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/hibp.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/jwt_rotation.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/lockout.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/models.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/org_invites.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/passwords.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/permissions.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/session.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/security/signed_cookies.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/utils.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/webhooks/__init__.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/webhooks/add.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/webhooks/fastapi.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/webhooks/router.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/src/svc_infra/webhooks/service.py +0 -0
- {svc_infra-0.1.622 → svc_infra-0.1.624}/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.
|
|
3
|
+
Version: 0.1.624
|
|
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
|
|
@@ -77,25 +77,34 @@ Description-Content-Type: text/markdown
|
|
|
77
77
|
# svc-infra
|
|
78
78
|
|
|
79
79
|
[](https://pypi.org/project/svc-infra/)
|
|
80
|
-
[](
|
|
80
|
+
[](.)
|
|
81
81
|
|
|
82
82
|
svc-infra packages the shared building blocks we use to ship production FastAPI services fast—HTTP APIs with secure auth, durable persistence, background execution, cache, observability, and webhook plumbing that all share the same batteries-included defaults.
|
|
83
83
|
|
|
84
84
|
## Helper index
|
|
85
85
|
|
|
86
|
-
|
|
|
86
|
+
| Area | What it covers | Guide |
|
|
87
87
|
| --- | --- | --- |
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
88
|
+
| Getting Started | Overview and entry points | [This page](getting-started.md) |
|
|
89
|
+
| Environment | Feature switches and env vars | [Environment](environment.md) |
|
|
90
|
+
| API | FastAPI bootstrap, middleware, docs wiring | [API guide](api.md) |
|
|
91
|
+
| Auth | Sessions, OAuth/OIDC, MFA, SMTP delivery | [Auth](auth.md) |
|
|
92
|
+
| Security | Password policy, lockout, signed cookies, headers | [Security](security.md) |
|
|
93
|
+
| Database | SQL + Mongo wiring, Alembic helpers, inbox/outbox patterns | [Database](database.md) |
|
|
94
|
+
| Tenancy | Multi-tenant boundaries and helpers | [Tenancy](tenancy.md) |
|
|
95
|
+
| Idempotency | Idempotent endpoints and middleware | [Idempotency](idempotency.md) |
|
|
96
|
+
| Rate Limiting | Middleware, dependency limiter, headers | [Rate limiting](rate-limiting.md) |
|
|
97
|
+
| Cache | cashews decorators, namespace management, TTL helpers | [Cache](cache.md) |
|
|
98
|
+
| Jobs | JobQueue, scheduler, CLI worker | [Jobs](jobs.md) |
|
|
99
|
+
| Observability | Prometheus, Grafana, OpenTelemetry | [Observability](observability.md) |
|
|
100
|
+
| Ops | Probes, breakers, SLOs & dashboards | [Ops](ops.md) |
|
|
101
|
+
| Webhooks | Subscription store, signing, retry worker | [Webhooks](webhooks.md) |
|
|
102
|
+
| CLI | Command groups for sql/mongo/obs/docs/dx/sdk/jobs | [CLI](cli.md) |
|
|
103
|
+
| Docs & SDKs | Publishing docs, generating SDKs | [Docs & SDKs](docs-and-sdks.md) |
|
|
104
|
+
| Acceptance | Acceptance harness and flows | [Acceptance](acceptance.md), [Matrix](acceptance-matrix.md) |
|
|
105
|
+
| Contributing | Dev setup and quality gates | [Contributing](contributing.md) |
|
|
106
|
+
| Repo Review | Checklist for releasing/PRs | [Repo review](repo-review.md) |
|
|
107
|
+
| Data Lifecycle | Fixtures, retention, erasure, backups | [Data lifecycle](data-lifecycle.md) |
|
|
99
108
|
|
|
100
109
|
## Minimal FastAPI bootstrap
|
|
101
110
|
|
|
@@ -123,9 +132,9 @@ async def handle_webhook(payload = Depends(require_signature(lambda: ["current",
|
|
|
123
132
|
- **API** – toggle logging/observability and docs exposure with `ENABLE_LOGGING`, `LOG_LEVEL`, `LOG_FORMAT`, `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and `CORS_ALLOW_ORIGINS`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/api/fastapi/setup.py†L47-L88】
|
|
124
133
|
- **Auth** – configure JWT secrets, SMTP, cookies, and policy using the `AUTH_…` settings family (e.g., `AUTH_JWT__SECRET`, `AUTH_SMTP_HOST`, `AUTH_SESSION_COOKIE_SECURE`). 【F:src/svc_infra/api/fastapi/auth/settings.py†L23-L91】
|
|
125
134
|
- **Database** – set connection URLs or components via `SQL_URL`/`SQL_URL_FILE`, `DB_DIALECT`, `DB_HOST`, `DB_USER`, `DB_PASSWORD`, plus Mongo knobs like `MONGO_URL`, `MONGO_DB`, and `MONGO_URL_FILE`. 【F:src/svc_infra/api/fastapi/db/sql/add.py†L55-L114】【F:src/svc_infra/db/sql/utils.py†L85-L206】【F:src/svc_infra/db/nosql/mongo/settings.py†L9-L13】【F:src/svc_infra/db/nosql/utils.py†L56-L113】
|
|
126
|
-
- **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:docs/jobs.md†L11-L48】
|
|
135
|
+
- **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:src/svc_infra/docs/jobs.md†L11-L48】
|
|
127
136
|
- **Cache** – namespace keys and lifetimes through `CACHE_PREFIX`, `CACHE_VERSION`, and TTL overrides `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG`. 【F:src/svc_infra/cache/README.md†L20-L173】【F:src/svc_infra/cache/ttl.py†L26-L55】
|
|
128
137
|
- **Observability** – turn metrics on/off or adjust scrape paths with `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and Prometheus/Grafana flags like `SVC_INFRA_DISABLE_PROMETHEUS`, `SVC_INFRA_RATE_WINDOW`, `SVC_INFRA_DASHBOARD_REFRESH`, `SVC_INFRA_DASHBOARD_RANGE`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/obs/metrics/asgi.py†L49-L206】【F:src/svc_infra/obs/cloud_dash.py†L85-L108】
|
|
129
|
-
- **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:docs/webhooks.md†L32-L53】
|
|
130
|
-
- **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:docs/security.md†L24-L70】
|
|
138
|
+
- **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:src/svc_infra/docs/webhooks.md†L32-L53】
|
|
139
|
+
- **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:src/svc_infra/docs/security.md†L24-L70】
|
|
131
140
|
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
# svc-infra
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/svc-infra/)
|
|
4
|
-
[](
|
|
4
|
+
[](.)
|
|
5
5
|
|
|
6
6
|
svc-infra packages the shared building blocks we use to ship production FastAPI services fast—HTTP APIs with secure auth, durable persistence, background execution, cache, observability, and webhook plumbing that all share the same batteries-included defaults.
|
|
7
7
|
|
|
8
8
|
## Helper index
|
|
9
9
|
|
|
10
|
-
|
|
|
10
|
+
| Area | What it covers | Guide |
|
|
11
11
|
| --- | --- | --- |
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
12
|
+
| Getting Started | Overview and entry points | [This page](getting-started.md) |
|
|
13
|
+
| Environment | Feature switches and env vars | [Environment](environment.md) |
|
|
14
|
+
| API | FastAPI bootstrap, middleware, docs wiring | [API guide](api.md) |
|
|
15
|
+
| Auth | Sessions, OAuth/OIDC, MFA, SMTP delivery | [Auth](auth.md) |
|
|
16
|
+
| Security | Password policy, lockout, signed cookies, headers | [Security](security.md) |
|
|
17
|
+
| Database | SQL + Mongo wiring, Alembic helpers, inbox/outbox patterns | [Database](database.md) |
|
|
18
|
+
| Tenancy | Multi-tenant boundaries and helpers | [Tenancy](tenancy.md) |
|
|
19
|
+
| Idempotency | Idempotent endpoints and middleware | [Idempotency](idempotency.md) |
|
|
20
|
+
| Rate Limiting | Middleware, dependency limiter, headers | [Rate limiting](rate-limiting.md) |
|
|
21
|
+
| Cache | cashews decorators, namespace management, TTL helpers | [Cache](cache.md) |
|
|
22
|
+
| Jobs | JobQueue, scheduler, CLI worker | [Jobs](jobs.md) |
|
|
23
|
+
| Observability | Prometheus, Grafana, OpenTelemetry | [Observability](observability.md) |
|
|
24
|
+
| Ops | Probes, breakers, SLOs & dashboards | [Ops](ops.md) |
|
|
25
|
+
| Webhooks | Subscription store, signing, retry worker | [Webhooks](webhooks.md) |
|
|
26
|
+
| CLI | Command groups for sql/mongo/obs/docs/dx/sdk/jobs | [CLI](cli.md) |
|
|
27
|
+
| Docs & SDKs | Publishing docs, generating SDKs | [Docs & SDKs](docs-and-sdks.md) |
|
|
28
|
+
| Acceptance | Acceptance harness and flows | [Acceptance](acceptance.md), [Matrix](acceptance-matrix.md) |
|
|
29
|
+
| Contributing | Dev setup and quality gates | [Contributing](contributing.md) |
|
|
30
|
+
| Repo Review | Checklist for releasing/PRs | [Repo review](repo-review.md) |
|
|
31
|
+
| Data Lifecycle | Fixtures, retention, erasure, backups | [Data lifecycle](data-lifecycle.md) |
|
|
23
32
|
|
|
24
33
|
## Minimal FastAPI bootstrap
|
|
25
34
|
|
|
@@ -47,8 +56,8 @@ async def handle_webhook(payload = Depends(require_signature(lambda: ["current",
|
|
|
47
56
|
- **API** – toggle logging/observability and docs exposure with `ENABLE_LOGGING`, `LOG_LEVEL`, `LOG_FORMAT`, `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and `CORS_ALLOW_ORIGINS`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/api/fastapi/setup.py†L47-L88】
|
|
48
57
|
- **Auth** – configure JWT secrets, SMTP, cookies, and policy using the `AUTH_…` settings family (e.g., `AUTH_JWT__SECRET`, `AUTH_SMTP_HOST`, `AUTH_SESSION_COOKIE_SECURE`). 【F:src/svc_infra/api/fastapi/auth/settings.py†L23-L91】
|
|
49
58
|
- **Database** – set connection URLs or components via `SQL_URL`/`SQL_URL_FILE`, `DB_DIALECT`, `DB_HOST`, `DB_USER`, `DB_PASSWORD`, plus Mongo knobs like `MONGO_URL`, `MONGO_DB`, and `MONGO_URL_FILE`. 【F:src/svc_infra/api/fastapi/db/sql/add.py†L55-L114】【F:src/svc_infra/db/sql/utils.py†L85-L206】【F:src/svc_infra/db/nosql/mongo/settings.py†L9-L13】【F:src/svc_infra/db/nosql/utils.py†L56-L113】
|
|
50
|
-
- **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:docs/jobs.md†L11-L48】
|
|
59
|
+
- **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:src/svc_infra/docs/jobs.md†L11-L48】
|
|
51
60
|
- **Cache** – namespace keys and lifetimes through `CACHE_PREFIX`, `CACHE_VERSION`, and TTL overrides `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG`. 【F:src/svc_infra/cache/README.md†L20-L173】【F:src/svc_infra/cache/ttl.py†L26-L55】
|
|
52
61
|
- **Observability** – turn metrics on/off or adjust scrape paths with `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and Prometheus/Grafana flags like `SVC_INFRA_DISABLE_PROMETHEUS`, `SVC_INFRA_RATE_WINDOW`, `SVC_INFRA_DASHBOARD_REFRESH`, `SVC_INFRA_DASHBOARD_RANGE`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/obs/metrics/asgi.py†L49-L206】【F:src/svc_infra/obs/cloud_dash.py†L85-L108】
|
|
53
|
-
- **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:docs/webhooks.md†L32-L53】
|
|
54
|
-
- **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:docs/security.md†L24-L70】
|
|
62
|
+
- **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:src/svc_infra/docs/webhooks.md†L32-L53】
|
|
63
|
+
- **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:src/svc_infra/docs/security.md†L24-L70】
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "svc-infra"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.624"
|
|
4
4
|
description = "Infrastructure for building and deploying prod-ready services"
|
|
5
5
|
authors = ["Ali Khatami <aliikhatami94@gmail.com>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -13,7 +13,7 @@ include = [
|
|
|
13
13
|
"src/svc_infra/obs/templates/**/*",
|
|
14
14
|
"src/svc_infra/obs/grafana/templates/**/*",
|
|
15
15
|
"src/svc_infra/obs/grafana/dashboards/**/*",
|
|
16
|
-
"docs/**/*"
|
|
16
|
+
"src/svc_infra/docs/**/*"
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
classifiers = [
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from importlib.resources import as_file
|
|
5
|
+
from importlib.resources import files as pkg_files
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Dict, List
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
import typer
|
|
11
|
+
from typer.core import TyperGroup
|
|
12
|
+
|
|
13
|
+
from svc_infra.app.root import resolve_project_root
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _norm(name: str) -> str:
|
|
17
|
+
return name.strip().lower().replace(" ", "-").replace("_", "-")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _discover_fs_topics(docs_dir: Path) -> Dict[str, Path]:
|
|
21
|
+
topics: Dict[str, Path] = {}
|
|
22
|
+
if docs_dir.exists() and docs_dir.is_dir():
|
|
23
|
+
for p in sorted(docs_dir.glob("*.md")):
|
|
24
|
+
if p.is_file():
|
|
25
|
+
topics[_norm(p.stem)] = p
|
|
26
|
+
return topics
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _discover_pkg_topics() -> Dict[str, Path]:
|
|
30
|
+
"""
|
|
31
|
+
Discover docs shipped inside the installed package at svc_infra/docs/*,
|
|
32
|
+
using importlib.resources so this works for wheels, sdists, and zipped wheels.
|
|
33
|
+
"""
|
|
34
|
+
topics: Dict[str, Path] = {}
|
|
35
|
+
try:
|
|
36
|
+
docs_root = pkg_files("svc_infra").joinpath("docs")
|
|
37
|
+
# docs_root is a Traversable; it may be inside a zip. Iterate safely.
|
|
38
|
+
for entry in docs_root.iterdir():
|
|
39
|
+
if entry.name.endswith(".md"):
|
|
40
|
+
# materialize to a real tempfile path if needed
|
|
41
|
+
with as_file(entry) as concrete:
|
|
42
|
+
p = Path(concrete)
|
|
43
|
+
if p.exists() and p.is_file():
|
|
44
|
+
topics[_norm(p.stem)] = p
|
|
45
|
+
except Exception:
|
|
46
|
+
# If the package has no docs directory, just return empty.
|
|
47
|
+
pass
|
|
48
|
+
return topics
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _resolve_docs_dir(ctx: click.Context) -> Path | None:
|
|
52
|
+
"""
|
|
53
|
+
Optional override precedence:
|
|
54
|
+
1) --docs-dir CLI option
|
|
55
|
+
2) SVC_INFRA_DOCS_DIR env var
|
|
56
|
+
3) *Only when working inside the svc-infra repo itself*: repo-root /docs
|
|
57
|
+
"""
|
|
58
|
+
# 1) CLI option on this or parent contexts
|
|
59
|
+
current: click.Context | None = ctx
|
|
60
|
+
while current is not None:
|
|
61
|
+
docs_dir_opt = (current.params or {}).get("docs_dir")
|
|
62
|
+
if docs_dir_opt:
|
|
63
|
+
path = docs_dir_opt if isinstance(docs_dir_opt, Path) else Path(docs_dir_opt)
|
|
64
|
+
path = path.expanduser()
|
|
65
|
+
if path.exists():
|
|
66
|
+
return path
|
|
67
|
+
current = current.parent
|
|
68
|
+
|
|
69
|
+
# 2) Env var
|
|
70
|
+
env_dir = os.getenv("SVC_INFRA_DOCS_DIR")
|
|
71
|
+
if env_dir:
|
|
72
|
+
p = Path(env_dir).expanduser()
|
|
73
|
+
if p.exists():
|
|
74
|
+
return p
|
|
75
|
+
|
|
76
|
+
# 3) In-repo convenience (so `svc-infra docs` works inside this repo)
|
|
77
|
+
try:
|
|
78
|
+
root = resolve_project_root()
|
|
79
|
+
proj_docs = root / "docs"
|
|
80
|
+
if proj_docs.exists():
|
|
81
|
+
return proj_docs
|
|
82
|
+
except Exception:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class DocsGroup(TyperGroup):
|
|
89
|
+
def list_commands(self, ctx: click.Context) -> List[str]:
|
|
90
|
+
names: List[str] = list(super().list_commands(ctx) or [])
|
|
91
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
92
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
93
|
+
pkg = _discover_pkg_topics()
|
|
94
|
+
names.extend(fs.keys())
|
|
95
|
+
names.extend([k for k in pkg.keys() if k not in fs])
|
|
96
|
+
return sorted(set(names))
|
|
97
|
+
|
|
98
|
+
def get_command(self, ctx: click.Context, name: str) -> click.Command | None:
|
|
99
|
+
cmd = super().get_command(ctx, name)
|
|
100
|
+
if cmd is not None:
|
|
101
|
+
return cmd
|
|
102
|
+
|
|
103
|
+
key = _norm(name)
|
|
104
|
+
|
|
105
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
106
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
107
|
+
if key in fs:
|
|
108
|
+
file_path = fs[key]
|
|
109
|
+
|
|
110
|
+
@click.command(name=name)
|
|
111
|
+
def _show_fs() -> None:
|
|
112
|
+
click.echo(file_path.read_text(encoding="utf-8", errors="replace"))
|
|
113
|
+
|
|
114
|
+
return _show_fs
|
|
115
|
+
|
|
116
|
+
pkg = _discover_pkg_topics()
|
|
117
|
+
if key in pkg:
|
|
118
|
+
file_path = pkg[key]
|
|
119
|
+
|
|
120
|
+
@click.command(name=name)
|
|
121
|
+
def _show_pkg() -> None:
|
|
122
|
+
click.echo(file_path.read_text(encoding="utf-8", errors="replace"))
|
|
123
|
+
|
|
124
|
+
return _show_pkg
|
|
125
|
+
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def register(app: typer.Typer) -> None:
|
|
130
|
+
docs_app = typer.Typer(no_args_is_help=True, add_completion=False, cls=DocsGroup)
|
|
131
|
+
|
|
132
|
+
@docs_app.callback(invoke_without_command=True)
|
|
133
|
+
def _docs_options(
|
|
134
|
+
docs_dir: Path | None = typer.Option(
|
|
135
|
+
None,
|
|
136
|
+
"--docs-dir",
|
|
137
|
+
help="Path to a docs directory to read from (overrides packaged docs)",
|
|
138
|
+
),
|
|
139
|
+
topic: str | None = typer.Option(None, "--topic", help="Topic to show directly"),
|
|
140
|
+
) -> None:
|
|
141
|
+
if topic:
|
|
142
|
+
key = _norm(topic)
|
|
143
|
+
ctx = click.get_current_context()
|
|
144
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
145
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
146
|
+
if key in fs:
|
|
147
|
+
typer.echo(fs[key].read_text(encoding="utf-8", errors="replace"))
|
|
148
|
+
raise typer.Exit(code=0)
|
|
149
|
+
pkg = _discover_pkg_topics()
|
|
150
|
+
if key in pkg:
|
|
151
|
+
typer.echo(pkg[key].read_text(encoding="utf-8", errors="replace"))
|
|
152
|
+
raise typer.Exit(code=0)
|
|
153
|
+
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
154
|
+
|
|
155
|
+
@docs_app.command("list", help="List available documentation topics")
|
|
156
|
+
def list_topics() -> None:
|
|
157
|
+
ctx = click.get_current_context()
|
|
158
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
159
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
160
|
+
pkg = _discover_pkg_topics()
|
|
161
|
+
|
|
162
|
+
def _print(name: str, path: Path) -> None:
|
|
163
|
+
try:
|
|
164
|
+
typer.echo(f"{name}\t{path}")
|
|
165
|
+
except Exception:
|
|
166
|
+
typer.echo(name)
|
|
167
|
+
|
|
168
|
+
for name, path in fs.items():
|
|
169
|
+
_print(name, path)
|
|
170
|
+
for name, path in pkg.items():
|
|
171
|
+
if name not in fs:
|
|
172
|
+
_print(name, path)
|
|
173
|
+
|
|
174
|
+
@docs_app.command("show", help="Show docs for a topic (alternative to dynamic subcommand)")
|
|
175
|
+
def show(topic: str) -> None:
|
|
176
|
+
key = _norm(topic)
|
|
177
|
+
ctx = click.get_current_context()
|
|
178
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
179
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
180
|
+
if key in fs:
|
|
181
|
+
typer.echo(fs[key].read_text(encoding="utf-8", errors="replace"))
|
|
182
|
+
return
|
|
183
|
+
pkg = _discover_pkg_topics()
|
|
184
|
+
if key in pkg:
|
|
185
|
+
typer.echo(pkg[key].read_text(encoding="utf-8", errors="replace"))
|
|
186
|
+
return
|
|
187
|
+
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
188
|
+
|
|
189
|
+
app.add_typer(docs_app, name="docs")
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# svc-infra
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/svc-infra/)
|
|
4
|
+
[](.)
|
|
5
|
+
|
|
6
|
+
svc-infra packages the shared building blocks we use to ship production FastAPI services fast—HTTP APIs with secure auth, durable persistence, background execution, cache, observability, and webhook plumbing that all share the same batteries-included defaults.
|
|
7
|
+
|
|
8
|
+
## Helper index
|
|
9
|
+
|
|
10
|
+
| Area | What it covers | Guide |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Getting Started | Overview and entry points | [This page](getting-started.md) |
|
|
13
|
+
| Environment | Feature switches and env vars | [Environment](environment.md) |
|
|
14
|
+
| API | FastAPI bootstrap, middleware, docs wiring | [API guide](api.md) |
|
|
15
|
+
| Auth | Sessions, OAuth/OIDC, MFA, SMTP delivery | [Auth](auth.md) |
|
|
16
|
+
| Security | Password policy, lockout, signed cookies, headers | [Security](security.md) |
|
|
17
|
+
| Database | SQL + Mongo wiring, Alembic helpers, inbox/outbox patterns | [Database](database.md) |
|
|
18
|
+
| Tenancy | Multi-tenant boundaries and helpers | [Tenancy](tenancy.md) |
|
|
19
|
+
| Idempotency | Idempotent endpoints and middleware | [Idempotency](idempotency.md) |
|
|
20
|
+
| Rate Limiting | Middleware, dependency limiter, headers | [Rate limiting](rate-limiting.md) |
|
|
21
|
+
| Cache | cashews decorators, namespace management, TTL helpers | [Cache](cache.md) |
|
|
22
|
+
| Jobs | JobQueue, scheduler, CLI worker | [Jobs](jobs.md) |
|
|
23
|
+
| Observability | Prometheus, Grafana, OpenTelemetry | [Observability](observability.md) |
|
|
24
|
+
| Ops | Probes, breakers, SLOs & dashboards | [Ops](ops.md) |
|
|
25
|
+
| Webhooks | Subscription store, signing, retry worker | [Webhooks](webhooks.md) |
|
|
26
|
+
| CLI | Command groups for sql/mongo/obs/docs/dx/sdk/jobs | [CLI](cli.md) |
|
|
27
|
+
| Docs & SDKs | Publishing docs, generating SDKs | [Docs & SDKs](docs-and-sdks.md) |
|
|
28
|
+
| Acceptance | Acceptance harness and flows | [Acceptance](acceptance.md), [Matrix](acceptance-matrix.md) |
|
|
29
|
+
| Contributing | Dev setup and quality gates | [Contributing](contributing.md) |
|
|
30
|
+
| Repo Review | Checklist for releasing/PRs | [Repo review](repo-review.md) |
|
|
31
|
+
| Data Lifecycle | Fixtures, retention, erasure, backups | [Data lifecycle](data-lifecycle.md) |
|
|
32
|
+
|
|
33
|
+
## Minimal FastAPI bootstrap
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from fastapi import Depends
|
|
37
|
+
from svc_infra.api.fastapi.ease import easy_service_app
|
|
38
|
+
from svc_infra.api.fastapi.db.sql.add import add_sql_db
|
|
39
|
+
from svc_infra.cache import init_cache
|
|
40
|
+
from svc_infra.jobs.easy import easy_jobs
|
|
41
|
+
from svc_infra.webhooks.fastapi import require_signature
|
|
42
|
+
|
|
43
|
+
app = easy_service_app(name="Billing", release="1.2.3")
|
|
44
|
+
add_sql_db(app) # reads SQL_URL / DB_* envs
|
|
45
|
+
init_cache() # honors CACHE_PREFIX / CACHE_VERSION
|
|
46
|
+
queue, scheduler = easy_jobs() # switches via JOBS_DRIVER / REDIS_URL
|
|
47
|
+
|
|
48
|
+
@app.post("/webhooks/billing")
|
|
49
|
+
async def handle_webhook(payload = Depends(require_signature(lambda: ["current", "next"]))):
|
|
50
|
+
queue.enqueue("process-billing-webhook", payload)
|
|
51
|
+
return {"status": "queued"}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Environment switches
|
|
55
|
+
|
|
56
|
+
- **API** – toggle logging/observability and docs exposure with `ENABLE_LOGGING`, `LOG_LEVEL`, `LOG_FORMAT`, `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and `CORS_ALLOW_ORIGINS`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/api/fastapi/setup.py†L47-L88】
|
|
57
|
+
- **Auth** – configure JWT secrets, SMTP, cookies, and policy using the `AUTH_…` settings family (e.g., `AUTH_JWT__SECRET`, `AUTH_SMTP_HOST`, `AUTH_SESSION_COOKIE_SECURE`). 【F:src/svc_infra/api/fastapi/auth/settings.py†L23-L91】
|
|
58
|
+
- **Database** – set connection URLs or components via `SQL_URL`/`SQL_URL_FILE`, `DB_DIALECT`, `DB_HOST`, `DB_USER`, `DB_PASSWORD`, plus Mongo knobs like `MONGO_URL`, `MONGO_DB`, and `MONGO_URL_FILE`. 【F:src/svc_infra/api/fastapi/db/sql/add.py†L55-L114】【F:src/svc_infra/db/sql/utils.py†L85-L206】【F:src/svc_infra/db/nosql/mongo/settings.py†L9-L13】【F:src/svc_infra/db/nosql/utils.py†L56-L113】
|
|
59
|
+
- **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:src/svc_infra/docs/jobs.md†L11-L48】
|
|
60
|
+
- **Cache** – namespace keys and lifetimes through `CACHE_PREFIX`, `CACHE_VERSION`, and TTL overrides `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG`. 【F:src/svc_infra/cache/README.md†L20-L173】【F:src/svc_infra/cache/ttl.py†L26-L55】
|
|
61
|
+
- **Observability** – turn metrics on/off or adjust scrape paths with `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and Prometheus/Grafana flags like `SVC_INFRA_DISABLE_PROMETHEUS`, `SVC_INFRA_RATE_WINDOW`, `SVC_INFRA_DASHBOARD_REFRESH`, `SVC_INFRA_DASHBOARD_RANGE`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/obs/metrics/asgi.py†L49-L206】【F:src/svc_infra/obs/cloud_dash.py†L85-L108】
|
|
62
|
+
- **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:src/svc_infra/docs/webhooks.md†L32-L53】
|
|
63
|
+
- **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:src/svc_infra/docs/security.md†L24-L70】
|
|
@@ -3,9 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
|
|
5
5
|
from ai_infra.llm.tools.custom.cli import cli_cmd_help, cli_subcmd_help
|
|
6
|
+
from ai_infra.mcp.server.tools import mcp_from_functions
|
|
7
|
+
|
|
6
8
|
from svc_infra.app.env import prepare_env
|
|
7
9
|
from svc_infra.cli.foundation.runner import run_from_root
|
|
8
|
-
from ai_infra.mcp.server.tools import mcp_from_functions
|
|
9
10
|
|
|
10
11
|
CLI_PROG = "svc-infra"
|
|
11
12
|
|
|
@@ -34,6 +35,7 @@ class Subcommand(str, Enum):
|
|
|
34
35
|
sql_scaffold_models = "sql scaffold-models"
|
|
35
36
|
sql_scaffold_schemas = "sql scaffold-schemas"
|
|
36
37
|
sql_export_tenant = "sql export-tenant"
|
|
38
|
+
sql_seed = "sql seed"
|
|
37
39
|
|
|
38
40
|
# Mongo group commands
|
|
39
41
|
mongo_prepare = "mongo prepare"
|
|
@@ -49,6 +51,24 @@ class Subcommand(str, Enum):
|
|
|
49
51
|
obs_down = "obs down"
|
|
50
52
|
obs_scaffold = "obs scaffold"
|
|
51
53
|
|
|
54
|
+
# Docs group
|
|
55
|
+
docs_list = "docs list"
|
|
56
|
+
docs_show = "docs show"
|
|
57
|
+
|
|
58
|
+
# DX group
|
|
59
|
+
dx_openapi = "dx openapi"
|
|
60
|
+
dx_migrations = "dx migrations"
|
|
61
|
+
dx_changelog = "dx changelog"
|
|
62
|
+
dx_ci = "dx ci"
|
|
63
|
+
|
|
64
|
+
# Jobs group
|
|
65
|
+
jobs_run = "jobs run"
|
|
66
|
+
|
|
67
|
+
# SDK group
|
|
68
|
+
sdk_ts = "sdk ts"
|
|
69
|
+
sdk_py = "sdk py"
|
|
70
|
+
sdk_postman = "sdk postman"
|
|
71
|
+
|
|
52
72
|
|
|
53
73
|
async def svc_infra_subcmd_help(subcommand: Subcommand) -> dict:
|
|
54
74
|
"""
|