svc-infra 0.1.615__tar.gz → 0.1.616__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.615 → svc_infra-0.1.616}/PKG-INFO +1 -1
- {svc_infra-0.1.615 → svc_infra-0.1.616}/pyproject.toml +3 -2
- svc_infra-0.1.616/src/svc_infra/bundled_docs/README.md +5 -0
- svc_infra-0.1.616/src/svc_infra/bundled_docs/__init__.py +1 -0
- svc_infra-0.1.616/src/svc_infra/bundled_docs/getting-started.md +6 -0
- svc_infra-0.1.616/src/svc_infra/cli/cmds/docs/docs_cmds.py +203 -0
- svc_infra-0.1.615/src/svc_infra/cli/cmds/docs/docs_cmds.py +0 -69
- {svc_infra-0.1.615 → svc_infra-0.1.616}/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/alembic.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/models.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/provider/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/provider/aiydan.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/provider/base.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/provider/registry.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/provider/stripe.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/schemas.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/apf_payments/settings.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/apf_payments/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/apf_payments/router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/apf_payments/setup.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/_cookies.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/gaurd.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/models.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/pre_auth.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/security.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/mfa/verify.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/policy.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/providers.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/account.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/session_router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/security.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/sender.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/settings.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/state.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/cache/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/cache/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/http.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/health.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/crud_router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/health.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/session.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/sql/users.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dependencies/ratelimit.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/docs/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/docs/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/docs/landing.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/docs/scoped.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/dualize.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/protected.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/public.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dual/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/dx.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/ease.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/http/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/http/concurrency.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/http/conditional.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/http/deprecation.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/debug.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/catchall.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/handlers.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/idempotency.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/idempotency_store.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/ratelimit.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/request_id.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/request_size_limit.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/apply.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/conventions.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/models.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/mutators.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/pipeline.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/responses.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/openapi/security.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/ops/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/pagination.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/paths/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/paths/auth.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/paths/generic.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/paths/prefix.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/paths/user.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/routers/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/routers/ping.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/setup.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/tenancy/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/tenancy/context.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/env.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/logging/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/logging/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/logging/filter.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/logging/formats.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/app/root.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/billing/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/billing/models.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/billing/service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/backend.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/decorators.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/demo.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/keys.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/recache.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/resources.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/tags.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/ttl.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cache/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/__main__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/nosql/mongo/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/sql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/sql/alembic_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/sql/sql_export_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/dx/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/dx/dx_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/help.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/jobs/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/jobs/jobs_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/obs/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/obs/obs_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/sdk/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/cmds/sdk/sdk_cmds.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/foundation/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/foundation/runner.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/cli/foundation/typer_bootstrap.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/data/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/data/backup.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/data/erasure.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/data/fixtures.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/data/retention.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/crud_schema.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/inbox.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/base.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/constants.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/core.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/indexes.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/management.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/client.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/settings.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/templates/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/templates/documents.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/templates/resources.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/mongo/templates/schemas.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/repository.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/resource.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/scaffold.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/service_with_hooks.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/types.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/nosql/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/outbox.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/apikey.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/authref.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/base.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/constants.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/core.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/management.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/repository.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/resource.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/scaffold.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/service_with_hooks.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/models_schemas/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/setup/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/setup/alembic.ini.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/setup/env_async.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/setup/env_sync.py.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/templates/setup/script.py.mako.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/tenant.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/types.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/uniq.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/uniq_hooks.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/sql/versioning.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/db/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/dx/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/dx/changelog.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/dx/checks.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/builtins/outbox_processor.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/builtins/webhook_delivery.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/easy.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/loader.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/queue.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/redis_queue.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/scheduler.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/jobs/worker.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/mcp/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/mcp/svc_infra_mcp.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/cloud_dash.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/grafana/dashboards/http-overview.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics/asgi.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics/base.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics/http.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics/sqlalchemy.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/metrics.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/compose_cloud/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/compose_cloud/templates/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/compose_cloud/templates/agent.yaml.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/compose_cloud/templates/docker-compose.cloud.yml.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/00_overview.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/10_http.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/20_db.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/30_runtime.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/40_clients.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/dashboards/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/docker-compose.yml.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/prometheus.yml.tmpl +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/provisioning/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/provisioning/dashboards.yml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/providers/grafana/templates/provisioning/datasource.yml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/settings.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/grafana_dashboard.json +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/prometheus_rules.yml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/compose/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/compose/agent.yaml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/compose/docker-compose.yml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/fly/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/fly/agent.yaml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/fly/fly.toml.fragment +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/k8s/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/k8s/configmap.yaml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/k8s/deployment.yaml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/railway/Dockerfile +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/railway/README.md +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/railway/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/obs/templates/sidecars/railway/agent.yaml +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/py.typed +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/audit.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/audit_service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/headers.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/hibp.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/jwt_rotation.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/lockout.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/models.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/org_invites.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/passwords.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/permissions.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/session.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/security/signed_cookies.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/utils.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/__init__.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/add.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/fastapi.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/router.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/service.py +0 -0
- {svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/webhooks/signing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "svc-infra"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.616"
|
|
4
4
|
description = "Infrastructure for building and deploying prod-ready services"
|
|
5
5
|
authors = ["Ali Khatami <aliikhatami94@gmail.com>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -12,7 +12,8 @@ include = [
|
|
|
12
12
|
"src/svc_infra/db/templates/**/*",
|
|
13
13
|
"src/svc_infra/obs/templates/**/*",
|
|
14
14
|
"src/svc_infra/obs/grafana/templates/**/*",
|
|
15
|
-
"src/svc_infra/obs/grafana/dashboards/**/*"
|
|
15
|
+
"src/svc_infra/obs/grafana/dashboards/**/*",
|
|
16
|
+
"src/svc_infra/bundled_docs/**/*"
|
|
16
17
|
]
|
|
17
18
|
|
|
18
19
|
classifiers = [
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Bundled Docs
|
|
2
|
+
|
|
3
|
+
This directory contains a minimal set of Markdown files that the `svc-infra docs` CLI can fall back to when the project running the CLI doesn't have a local `docs/` directory.
|
|
4
|
+
|
|
5
|
+
You can add more topics here as needed; each `*.md` file becomes a topic named after its stem (e.g., `getting-started.md` -> `getting-started`).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Bundled docs package for zip-safe importlib.resources access
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Dict, List
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
import typer
|
|
9
|
+
from typer.core import TyperGroup
|
|
10
|
+
|
|
11
|
+
from svc_infra.app.root import resolve_project_root
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _discover_fs_topics(docs_dir: Path) -> Dict[str, Path]:
|
|
15
|
+
topics: Dict[str, Path] = {}
|
|
16
|
+
if docs_dir.exists() and docs_dir.is_dir():
|
|
17
|
+
for p in sorted(docs_dir.glob("*.md")):
|
|
18
|
+
if p.is_file():
|
|
19
|
+
topics[p.stem.replace(" ", "-")] = p
|
|
20
|
+
return topics
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _discover_pkg_topics() -> Dict[str, object]:
|
|
24
|
+
topics: Dict[str, object] = {}
|
|
25
|
+
try:
|
|
26
|
+
import importlib.resources as ir
|
|
27
|
+
|
|
28
|
+
pkg_docs = ir.files("svc_infra.bundled_docs")
|
|
29
|
+
for res in pkg_docs.iterdir():
|
|
30
|
+
if res.name.endswith(".md"):
|
|
31
|
+
topics[Path(res.name).stem.replace(" ", "-")] = res
|
|
32
|
+
except Exception:
|
|
33
|
+
pass
|
|
34
|
+
return topics
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _resolve_docs_dir(ctx: click.Context) -> Path | None:
|
|
38
|
+
# CLI option takes precedence; walk up parent contexts because Typer
|
|
39
|
+
# executes subcommands in child contexts that do not inherit params.
|
|
40
|
+
current: click.Context | None = ctx
|
|
41
|
+
while current is not None:
|
|
42
|
+
docs_dir = (current.params or {}).get("docs_dir")
|
|
43
|
+
if docs_dir:
|
|
44
|
+
path = docs_dir if isinstance(docs_dir, Path) else Path(docs_dir)
|
|
45
|
+
path = path.expanduser()
|
|
46
|
+
if path.exists():
|
|
47
|
+
return path
|
|
48
|
+
current = current.parent
|
|
49
|
+
# Env var next
|
|
50
|
+
env_dir = os.getenv("SVC_INFRA_DOCS_DIR")
|
|
51
|
+
if env_dir:
|
|
52
|
+
p = Path(env_dir).expanduser()
|
|
53
|
+
if p.exists():
|
|
54
|
+
return p
|
|
55
|
+
# Project docs
|
|
56
|
+
root = resolve_project_root()
|
|
57
|
+
proj_docs = root / "docs"
|
|
58
|
+
if proj_docs.exists():
|
|
59
|
+
return proj_docs
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class DocsGroup(TyperGroup):
|
|
64
|
+
def list_commands(self, ctx: click.Context) -> List[str]:
|
|
65
|
+
names: List[str] = list(super().list_commands(ctx) or [])
|
|
66
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
67
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
68
|
+
pkg = _discover_pkg_topics() if not fs else {}
|
|
69
|
+
names.extend(fs.keys())
|
|
70
|
+
names.extend(pkg.keys())
|
|
71
|
+
# Deduplicate and sort
|
|
72
|
+
uniq = sorted({*names})
|
|
73
|
+
return uniq
|
|
74
|
+
|
|
75
|
+
def get_command(self, ctx: click.Context, name: str) -> click.Command | None:
|
|
76
|
+
# Built-ins first (e.g., list)
|
|
77
|
+
cmd = super().get_command(ctx, name)
|
|
78
|
+
if cmd is not None:
|
|
79
|
+
return cmd
|
|
80
|
+
|
|
81
|
+
# Dynamic topic resolution
|
|
82
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
83
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
84
|
+
if name in fs:
|
|
85
|
+
file_path = fs[name]
|
|
86
|
+
|
|
87
|
+
@click.command(name=name)
|
|
88
|
+
def _show_fs() -> None:
|
|
89
|
+
click.echo(file_path.read_text(encoding="utf-8", errors="replace"))
|
|
90
|
+
|
|
91
|
+
return _show_fs
|
|
92
|
+
|
|
93
|
+
if not fs:
|
|
94
|
+
pkg = _discover_pkg_topics()
|
|
95
|
+
if name in pkg:
|
|
96
|
+
res = pkg[name]
|
|
97
|
+
|
|
98
|
+
@click.command(name=name)
|
|
99
|
+
def _show_pkg() -> None:
|
|
100
|
+
try:
|
|
101
|
+
import importlib.resources as ir
|
|
102
|
+
|
|
103
|
+
content = getattr(res, "read_text", None)
|
|
104
|
+
if callable(content):
|
|
105
|
+
text = content(encoding="utf-8", errors="replace")
|
|
106
|
+
else:
|
|
107
|
+
with ir.as_file(res) as p:
|
|
108
|
+
text = Path(p).read_text(encoding="utf-8", errors="replace")
|
|
109
|
+
click.echo(text)
|
|
110
|
+
except Exception as e: # pragma: no cover
|
|
111
|
+
raise click.ClickException(f"Failed to load bundled doc: {e}")
|
|
112
|
+
|
|
113
|
+
return _show_pkg
|
|
114
|
+
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def register(app: typer.Typer) -> None:
|
|
119
|
+
"""Register the `docs` command group with dynamic topic subcommands."""
|
|
120
|
+
|
|
121
|
+
docs_app = typer.Typer(no_args_is_help=True, add_completion=False, cls=DocsGroup)
|
|
122
|
+
|
|
123
|
+
@docs_app.callback(invoke_without_command=True)
|
|
124
|
+
def _docs_options(
|
|
125
|
+
docs_dir: Path | None = typer.Option(
|
|
126
|
+
None,
|
|
127
|
+
"--docs-dir",
|
|
128
|
+
help="Path to a docs directory to read from (overrides env/project root)",
|
|
129
|
+
),
|
|
130
|
+
topic: str | None = typer.Option(None, "--topic", help="Topic to show directly"),
|
|
131
|
+
) -> None:
|
|
132
|
+
"""Support --docs-dir and --topic at group level."""
|
|
133
|
+
if topic:
|
|
134
|
+
ctx = click.get_current_context()
|
|
135
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
136
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
137
|
+
if topic in fs:
|
|
138
|
+
typer.echo(fs[topic].read_text(encoding="utf-8", errors="replace"))
|
|
139
|
+
raise typer.Exit(code=0)
|
|
140
|
+
if not fs:
|
|
141
|
+
pkg = _discover_pkg_topics()
|
|
142
|
+
if topic in pkg:
|
|
143
|
+
try:
|
|
144
|
+
import importlib.resources as ir
|
|
145
|
+
|
|
146
|
+
res = pkg[topic]
|
|
147
|
+
content = getattr(res, "read_text", None)
|
|
148
|
+
if callable(content):
|
|
149
|
+
text = content(encoding="utf-8", errors="replace")
|
|
150
|
+
else:
|
|
151
|
+
with ir.as_file(res) as p:
|
|
152
|
+
text = Path(p).read_text(encoding="utf-8", errors="replace")
|
|
153
|
+
typer.echo(text)
|
|
154
|
+
raise typer.Exit(code=0)
|
|
155
|
+
except Exception as e: # pragma: no cover
|
|
156
|
+
raise typer.BadParameter(f"Failed to load bundled topic '{topic}': {e}")
|
|
157
|
+
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
158
|
+
|
|
159
|
+
@docs_app.command("list", help="List available documentation topics")
|
|
160
|
+
def list_topics() -> None:
|
|
161
|
+
ctx = click.get_current_context()
|
|
162
|
+
root = resolve_project_root()
|
|
163
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
164
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
165
|
+
pkg = _discover_pkg_topics() if not fs else {}
|
|
166
|
+
for name, path in fs.items():
|
|
167
|
+
try:
|
|
168
|
+
rel = path.relative_to(root)
|
|
169
|
+
typer.echo(f"{name}\t{rel}")
|
|
170
|
+
except Exception:
|
|
171
|
+
typer.echo(f"{name}\t{path}")
|
|
172
|
+
for name in sorted(pkg.keys()):
|
|
173
|
+
typer.echo(f"{name}\t(bundled)")
|
|
174
|
+
|
|
175
|
+
# Also support a generic "show" command
|
|
176
|
+
@docs_app.command("show", help="Show docs for a topic (alternative to dynamic subcommand)")
|
|
177
|
+
def show(topic: str) -> None:
|
|
178
|
+
ctx = click.get_current_context()
|
|
179
|
+
dir_to_use = _resolve_docs_dir(ctx)
|
|
180
|
+
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
181
|
+
if topic in fs:
|
|
182
|
+
typer.echo(fs[topic].read_text(encoding="utf-8", errors="replace"))
|
|
183
|
+
return
|
|
184
|
+
if not fs:
|
|
185
|
+
pkg = _discover_pkg_topics()
|
|
186
|
+
if topic in pkg:
|
|
187
|
+
try:
|
|
188
|
+
import importlib.resources as ir
|
|
189
|
+
|
|
190
|
+
res = pkg[topic]
|
|
191
|
+
content = getattr(res, "read_text", None)
|
|
192
|
+
if callable(content):
|
|
193
|
+
text = content(encoding="utf-8", errors="replace")
|
|
194
|
+
else:
|
|
195
|
+
with ir.as_file(res) as p:
|
|
196
|
+
text = Path(p).read_text(encoding="utf-8", errors="replace")
|
|
197
|
+
typer.echo(text)
|
|
198
|
+
return
|
|
199
|
+
except Exception as e: # pragma: no cover
|
|
200
|
+
raise typer.BadParameter(f"Failed to load bundled topic '{topic}': {e}")
|
|
201
|
+
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
202
|
+
|
|
203
|
+
app.add_typer(docs_app, name="docs")
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Dict, List, Tuple
|
|
5
|
-
|
|
6
|
-
import typer
|
|
7
|
-
|
|
8
|
-
from svc_infra.app.root import resolve_project_root
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def _discover_docs(root: Path) -> List[Tuple[str, Path]]:
|
|
12
|
-
"""Return a list of (topic, file_path) for top-level Markdown files under docs/.
|
|
13
|
-
|
|
14
|
-
Topic is the filename stem (e.g. security.md -> "security").
|
|
15
|
-
"""
|
|
16
|
-
docs_dir = root / "docs"
|
|
17
|
-
topics: List[Tuple[str, Path]] = []
|
|
18
|
-
if not docs_dir.exists() or not docs_dir.is_dir():
|
|
19
|
-
return topics
|
|
20
|
-
for p in sorted(docs_dir.glob("*.md")):
|
|
21
|
-
if p.is_file():
|
|
22
|
-
topics.append((p.stem.replace(" ", "-"), p))
|
|
23
|
-
return topics
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def register(app: typer.Typer) -> None:
|
|
27
|
-
"""Register the `docs` command group and dynamic topic subcommands."""
|
|
28
|
-
|
|
29
|
-
root = resolve_project_root()
|
|
30
|
-
discovered = _discover_docs(root)
|
|
31
|
-
|
|
32
|
-
# Build help text listing available topics
|
|
33
|
-
if discovered:
|
|
34
|
-
topic_names = ", ".join(name for name, _ in discovered)
|
|
35
|
-
docs_help = (
|
|
36
|
-
f"Show docs from the repository's docs/ directory.\n\nAvailable topics: {topic_names}"
|
|
37
|
-
)
|
|
38
|
-
else:
|
|
39
|
-
docs_help = "Show docs from the repository's docs/ directory.\n\nNo topics discovered."
|
|
40
|
-
|
|
41
|
-
docs_app = typer.Typer(no_args_is_help=True, help=docs_help, add_completion=False)
|
|
42
|
-
|
|
43
|
-
@docs_app.command("list", help="List available documentation topics")
|
|
44
|
-
def list_topics() -> None:
|
|
45
|
-
for name, path in discovered:
|
|
46
|
-
typer.echo(f"{name}\t{path.relative_to(root)}")
|
|
47
|
-
|
|
48
|
-
# Freeze mapping for use in dynamic commands and generic fallback
|
|
49
|
-
topic_map: Dict[str, Path] = {name: path for name, path in discovered}
|
|
50
|
-
|
|
51
|
-
def _make_topic_cmd(topic: str, file_path: Path):
|
|
52
|
-
@docs_app.command(name=topic, help=f"Show docs for topic: {topic}")
|
|
53
|
-
def _show_topic() -> None: # noqa: WPS430 (nested function OK for closure)
|
|
54
|
-
content = file_path.read_text(encoding="utf-8", errors="replace")
|
|
55
|
-
typer.echo(content)
|
|
56
|
-
|
|
57
|
-
for name, path in discovered:
|
|
58
|
-
_make_topic_cmd(name, path)
|
|
59
|
-
|
|
60
|
-
# Optional generic fallback: allow `svc-infra docs --topic <name>`
|
|
61
|
-
@docs_app.callback(invoke_without_command=True)
|
|
62
|
-
def _maybe_show_topic(topic: str = typer.Option(None, "--topic", help="Topic to show")) -> None: # type: ignore[no-redef]
|
|
63
|
-
if topic:
|
|
64
|
-
p = topic_map.get(topic)
|
|
65
|
-
if not p:
|
|
66
|
-
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
67
|
-
typer.echo(p.read_text(encoding="utf-8", errors="replace"))
|
|
68
|
-
|
|
69
|
-
app.add_typer(docs_app, name="docs")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/apikey_router.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/oauth_router.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/auth/routers/session_router.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/db/nosql/mongo/crud_router.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/__init__.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/catchall.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/exceptions.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/errors/handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/idempotency_store.py
RENAMED
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/optimistic_lock.py
RENAMED
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/ratelimit_store.py
RENAMED
|
File without changes
|
|
File without changes
|
{svc_infra-0.1.615 → svc_infra-0.1.616}/src/svc_infra/api/fastapi/middleware/request_size_limit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|