svc-infra 0.1.562__py3-none-any.whl → 0.1.654__py3-none-any.whl
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.
- svc_infra/apf_payments/README.md +732 -0
- svc_infra/apf_payments/models.py +142 -4
- svc_infra/apf_payments/provider/__init__.py +4 -0
- svc_infra/apf_payments/provider/aiydan.py +797 -0
- svc_infra/apf_payments/provider/base.py +178 -12
- svc_infra/apf_payments/provider/stripe.py +757 -48
- svc_infra/apf_payments/schemas.py +163 -1
- svc_infra/apf_payments/service.py +582 -42
- svc_infra/apf_payments/settings.py +22 -2
- svc_infra/api/fastapi/admin/__init__.py +3 -0
- svc_infra/api/fastapi/admin/add.py +231 -0
- svc_infra/api/fastapi/apf_payments/router.py +792 -73
- svc_infra/api/fastapi/apf_payments/setup.py +13 -4
- svc_infra/api/fastapi/auth/add.py +10 -4
- svc_infra/api/fastapi/auth/gaurd.py +67 -5
- svc_infra/api/fastapi/auth/routers/oauth_router.py +74 -34
- svc_infra/api/fastapi/auth/routers/session_router.py +63 -0
- svc_infra/api/fastapi/auth/settings.py +2 -0
- svc_infra/api/fastapi/billing/router.py +64 -0
- svc_infra/api/fastapi/billing/setup.py +19 -0
- svc_infra/api/fastapi/cache/add.py +9 -5
- svc_infra/api/fastapi/db/nosql/mongo/add.py +33 -27
- svc_infra/api/fastapi/db/sql/add.py +40 -18
- svc_infra/api/fastapi/db/sql/crud_router.py +176 -14
- svc_infra/api/fastapi/db/sql/session.py +16 -0
- svc_infra/api/fastapi/db/sql/users.py +13 -1
- svc_infra/api/fastapi/dependencies/ratelimit.py +116 -0
- svc_infra/api/fastapi/docs/add.py +160 -0
- svc_infra/api/fastapi/docs/landing.py +1 -1
- svc_infra/api/fastapi/docs/scoped.py +41 -6
- svc_infra/api/fastapi/middleware/errors/handlers.py +45 -7
- svc_infra/api/fastapi/middleware/graceful_shutdown.py +87 -0
- svc_infra/api/fastapi/middleware/idempotency.py +82 -42
- svc_infra/api/fastapi/middleware/idempotency_store.py +187 -0
- svc_infra/api/fastapi/middleware/optimistic_lock.py +37 -0
- svc_infra/api/fastapi/middleware/ratelimit.py +84 -11
- svc_infra/api/fastapi/middleware/ratelimit_store.py +84 -0
- svc_infra/api/fastapi/middleware/request_size_limit.py +36 -0
- svc_infra/api/fastapi/middleware/timeout.py +148 -0
- svc_infra/api/fastapi/openapi/mutators.py +244 -38
- svc_infra/api/fastapi/ops/add.py +73 -0
- svc_infra/api/fastapi/pagination.py +133 -32
- svc_infra/api/fastapi/routers/ping.py +1 -0
- svc_infra/api/fastapi/setup.py +23 -14
- svc_infra/api/fastapi/tenancy/add.py +19 -0
- svc_infra/api/fastapi/tenancy/context.py +112 -0
- svc_infra/api/fastapi/versioned.py +101 -0
- svc_infra/app/README.md +5 -5
- svc_infra/billing/__init__.py +23 -0
- svc_infra/billing/async_service.py +147 -0
- svc_infra/billing/jobs.py +230 -0
- svc_infra/billing/models.py +131 -0
- svc_infra/billing/quotas.py +101 -0
- svc_infra/billing/schemas.py +33 -0
- svc_infra/billing/service.py +115 -0
- svc_infra/bundled_docs/README.md +5 -0
- svc_infra/bundled_docs/__init__.py +1 -0
- svc_infra/bundled_docs/getting-started.md +6 -0
- svc_infra/cache/__init__.py +4 -0
- svc_infra/cache/add.py +158 -0
- svc_infra/cache/backend.py +5 -2
- svc_infra/cache/decorators.py +19 -1
- svc_infra/cache/keys.py +24 -4
- svc_infra/cli/__init__.py +32 -8
- svc_infra/cli/__main__.py +4 -0
- svc_infra/cli/cmds/__init__.py +10 -0
- svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +4 -3
- svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +4 -4
- svc_infra/cli/cmds/db/sql/alembic_cmds.py +80 -11
- svc_infra/cli/cmds/db/sql/sql_export_cmds.py +80 -0
- svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +3 -3
- svc_infra/cli/cmds/docs/docs_cmds.py +140 -0
- svc_infra/cli/cmds/dx/__init__.py +12 -0
- svc_infra/cli/cmds/dx/dx_cmds.py +99 -0
- svc_infra/cli/cmds/help.py +4 -0
- svc_infra/cli/cmds/jobs/__init__.py +1 -0
- svc_infra/cli/cmds/jobs/jobs_cmds.py +43 -0
- svc_infra/cli/cmds/obs/obs_cmds.py +4 -3
- svc_infra/cli/cmds/sdk/__init__.py +0 -0
- svc_infra/cli/cmds/sdk/sdk_cmds.py +102 -0
- svc_infra/data/add.py +61 -0
- svc_infra/data/backup.py +53 -0
- svc_infra/data/erasure.py +45 -0
- svc_infra/data/fixtures.py +40 -0
- svc_infra/data/retention.py +55 -0
- svc_infra/db/inbox.py +67 -0
- svc_infra/db/nosql/mongo/README.md +13 -13
- svc_infra/db/outbox.py +104 -0
- svc_infra/db/sql/repository.py +52 -12
- svc_infra/db/sql/resource.py +5 -0
- svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +1 -1
- svc_infra/db/sql/templates/setup/env_async.py.tmpl +13 -8
- svc_infra/db/sql/templates/setup/env_sync.py.tmpl +9 -5
- svc_infra/db/sql/tenant.py +79 -0
- svc_infra/db/sql/utils.py +18 -4
- svc_infra/db/sql/versioning.py +14 -0
- svc_infra/docs/acceptance-matrix.md +71 -0
- svc_infra/docs/acceptance.md +44 -0
- svc_infra/docs/admin.md +425 -0
- svc_infra/docs/adr/0002-background-jobs-and-scheduling.md +40 -0
- svc_infra/docs/adr/0003-webhooks-framework.md +24 -0
- svc_infra/docs/adr/0004-tenancy-model.md +42 -0
- svc_infra/docs/adr/0005-data-lifecycle.md +86 -0
- svc_infra/docs/adr/0006-ops-slos-and-metrics.md +47 -0
- svc_infra/docs/adr/0007-docs-and-sdks.md +83 -0
- svc_infra/docs/adr/0008-billing-primitives.md +143 -0
- svc_infra/docs/adr/0009-acceptance-harness.md +40 -0
- svc_infra/docs/adr/0010-timeouts-and-resource-limits.md +54 -0
- svc_infra/docs/adr/0011-admin-scope-and-impersonation.md +73 -0
- svc_infra/docs/api.md +59 -0
- svc_infra/docs/auth.md +11 -0
- svc_infra/docs/billing.md +190 -0
- svc_infra/docs/cache.md +76 -0
- svc_infra/docs/cli.md +74 -0
- svc_infra/docs/contributing.md +34 -0
- svc_infra/docs/data-lifecycle.md +52 -0
- svc_infra/docs/database.md +14 -0
- svc_infra/docs/docs-and-sdks.md +62 -0
- svc_infra/docs/environment.md +114 -0
- svc_infra/docs/getting-started.md +63 -0
- svc_infra/docs/idempotency.md +111 -0
- svc_infra/docs/jobs.md +67 -0
- svc_infra/docs/observability.md +16 -0
- svc_infra/docs/ops.md +37 -0
- svc_infra/docs/rate-limiting.md +125 -0
- svc_infra/docs/repo-review.md +48 -0
- svc_infra/docs/security.md +176 -0
- svc_infra/docs/tenancy.md +35 -0
- svc_infra/docs/timeouts-and-resource-limits.md +147 -0
- svc_infra/docs/versioned-integrations.md +146 -0
- svc_infra/docs/webhooks.md +112 -0
- svc_infra/dx/add.py +63 -0
- svc_infra/dx/changelog.py +74 -0
- svc_infra/dx/checks.py +67 -0
- svc_infra/http/__init__.py +13 -0
- svc_infra/http/client.py +72 -0
- svc_infra/jobs/builtins/outbox_processor.py +38 -0
- svc_infra/jobs/builtins/webhook_delivery.py +90 -0
- svc_infra/jobs/easy.py +32 -0
- svc_infra/jobs/loader.py +45 -0
- svc_infra/jobs/queue.py +81 -0
- svc_infra/jobs/redis_queue.py +191 -0
- svc_infra/jobs/runner.py +75 -0
- svc_infra/jobs/scheduler.py +41 -0
- svc_infra/jobs/worker.py +40 -0
- svc_infra/mcp/svc_infra_mcp.py +85 -28
- svc_infra/obs/README.md +2 -0
- svc_infra/obs/add.py +54 -7
- svc_infra/obs/grafana/dashboards/http-overview.json +45 -0
- svc_infra/obs/metrics/__init__.py +53 -0
- svc_infra/obs/metrics.py +52 -0
- svc_infra/security/add.py +201 -0
- svc_infra/security/audit.py +130 -0
- svc_infra/security/audit_service.py +73 -0
- svc_infra/security/headers.py +52 -0
- svc_infra/security/hibp.py +95 -0
- svc_infra/security/jwt_rotation.py +53 -0
- svc_infra/security/lockout.py +96 -0
- svc_infra/security/models.py +255 -0
- svc_infra/security/org_invites.py +128 -0
- svc_infra/security/passwords.py +77 -0
- svc_infra/security/permissions.py +149 -0
- svc_infra/security/session.py +98 -0
- svc_infra/security/signed_cookies.py +80 -0
- svc_infra/webhooks/__init__.py +16 -0
- svc_infra/webhooks/add.py +322 -0
- svc_infra/webhooks/fastapi.py +37 -0
- svc_infra/webhooks/router.py +55 -0
- svc_infra/webhooks/service.py +67 -0
- svc_infra/webhooks/signing.py +30 -0
- svc_infra-0.1.654.dist-info/METADATA +154 -0
- {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/RECORD +174 -56
- svc_infra-0.1.562.dist-info/METADATA +0 -79
- {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/WHEEL +0 -0
- {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/entry_points.txt +0 -0
|
@@ -3,58 +3,65 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any, Optional, Protocol
|
|
4
4
|
|
|
5
5
|
from ..schemas import (
|
|
6
|
+
BalanceSnapshotOut,
|
|
6
7
|
CustomerOut,
|
|
7
8
|
CustomerUpsertIn,
|
|
9
|
+
DisputeOut,
|
|
8
10
|
IntentCreateIn,
|
|
9
11
|
IntentOut,
|
|
10
12
|
InvoiceCreateIn,
|
|
13
|
+
InvoiceLineItemIn,
|
|
14
|
+
InvoiceLineItemOut,
|
|
11
15
|
InvoiceOut,
|
|
12
16
|
PaymentMethodAttachIn,
|
|
13
17
|
PaymentMethodOut,
|
|
18
|
+
PaymentMethodUpdateIn,
|
|
19
|
+
PayoutOut,
|
|
14
20
|
PriceCreateIn,
|
|
15
21
|
PriceOut,
|
|
22
|
+
PriceUpdateIn,
|
|
16
23
|
ProductCreateIn,
|
|
17
24
|
ProductOut,
|
|
25
|
+
ProductUpdateIn,
|
|
18
26
|
RefundIn,
|
|
27
|
+
RefundOut,
|
|
28
|
+
SetupIntentCreateIn,
|
|
29
|
+
SetupIntentOut,
|
|
19
30
|
SubscriptionCreateIn,
|
|
20
31
|
SubscriptionOut,
|
|
21
32
|
SubscriptionUpdateIn,
|
|
33
|
+
UsageRecordIn,
|
|
34
|
+
UsageRecordListFilter,
|
|
35
|
+
UsageRecordOut,
|
|
22
36
|
)
|
|
23
37
|
|
|
24
38
|
|
|
25
39
|
class ProviderAdapter(Protocol):
|
|
26
40
|
name: str
|
|
27
41
|
|
|
28
|
-
# Customers
|
|
29
42
|
async def ensure_customer(self, data: CustomerUpsertIn) -> CustomerOut:
|
|
30
43
|
pass
|
|
31
44
|
|
|
32
|
-
async def get_customer(self, provider_customer_id: str) -> Optional[CustomerOut]:
|
|
33
|
-
pass
|
|
34
|
-
|
|
35
|
-
# Payment Methods
|
|
36
45
|
async def attach_payment_method(self, data: PaymentMethodAttachIn) -> PaymentMethodOut:
|
|
37
46
|
pass
|
|
38
47
|
|
|
39
48
|
async def list_payment_methods(self, provider_customer_id: str) -> list[PaymentMethodOut]:
|
|
40
49
|
pass
|
|
41
50
|
|
|
42
|
-
async def detach_payment_method(self, provider_method_id: str) ->
|
|
51
|
+
async def detach_payment_method(self, provider_method_id: str) -> PaymentMethodOut:
|
|
43
52
|
pass
|
|
44
53
|
|
|
45
54
|
async def set_default_payment_method(
|
|
46
55
|
self, provider_customer_id: str, provider_method_id: str
|
|
47
|
-
) ->
|
|
56
|
+
) -> PaymentMethodOut:
|
|
48
57
|
pass
|
|
49
58
|
|
|
50
|
-
# Products / Prices
|
|
51
59
|
async def create_product(self, data: ProductCreateIn) -> ProductOut:
|
|
52
60
|
pass
|
|
53
61
|
|
|
54
62
|
async def create_price(self, data: PriceCreateIn) -> PriceOut:
|
|
55
63
|
pass
|
|
56
64
|
|
|
57
|
-
# Subscriptions
|
|
58
65
|
async def create_subscription(self, data: SubscriptionCreateIn) -> SubscriptionOut:
|
|
59
66
|
pass
|
|
60
67
|
|
|
@@ -68,7 +75,6 @@ class ProviderAdapter(Protocol):
|
|
|
68
75
|
) -> SubscriptionOut:
|
|
69
76
|
pass
|
|
70
77
|
|
|
71
|
-
# Invoices
|
|
72
78
|
async def create_invoice(self, data: InvoiceCreateIn) -> InvoiceOut:
|
|
73
79
|
pass
|
|
74
80
|
|
|
@@ -81,7 +87,6 @@ class ProviderAdapter(Protocol):
|
|
|
81
87
|
async def pay_invoice(self, provider_invoice_id: str) -> InvoiceOut:
|
|
82
88
|
pass
|
|
83
89
|
|
|
84
|
-
# Intents
|
|
85
90
|
async def create_intent(self, data: IntentCreateIn, *, user_id: str | None) -> IntentOut:
|
|
86
91
|
pass
|
|
87
92
|
|
|
@@ -97,8 +102,169 @@ class ProviderAdapter(Protocol):
|
|
|
97
102
|
async def hydrate_intent(self, provider_intent_id: str) -> IntentOut:
|
|
98
103
|
pass
|
|
99
104
|
|
|
100
|
-
# Webhooks
|
|
101
105
|
async def verify_and_parse_webhook(
|
|
102
106
|
self, signature: str | None, payload: bytes
|
|
103
107
|
) -> dict[str, Any]:
|
|
104
108
|
pass
|
|
109
|
+
|
|
110
|
+
async def capture_intent(self, provider_intent_id: str, *, amount: int | None) -> IntentOut:
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
async def list_intents(
|
|
114
|
+
self,
|
|
115
|
+
*,
|
|
116
|
+
customer_provider_id: str | None,
|
|
117
|
+
status: str | None,
|
|
118
|
+
limit: int,
|
|
119
|
+
cursor: str | None,
|
|
120
|
+
) -> tuple[list[IntentOut], str | None]:
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
async def add_invoice_line_item(
|
|
124
|
+
self, provider_invoice_id: str, data: InvoiceLineItemIn
|
|
125
|
+
) -> InvoiceOut:
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
async def list_invoices(
|
|
129
|
+
self,
|
|
130
|
+
*,
|
|
131
|
+
customer_provider_id: str | None,
|
|
132
|
+
status: str | None,
|
|
133
|
+
limit: int,
|
|
134
|
+
cursor: str | None,
|
|
135
|
+
) -> tuple[list[InvoiceOut], str | None]:
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
async def get_invoice(self, provider_invoice_id: str) -> InvoiceOut:
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
async def preview_invoice(
|
|
142
|
+
self, *, customer_provider_id: str, subscription_id: str | None = None
|
|
143
|
+
) -> InvoiceOut:
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
async def create_usage_record(self, data: UsageRecordIn) -> UsageRecordOut:
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
# --- Setup Intents ---
|
|
150
|
+
async def create_setup_intent(self, data: SetupIntentCreateIn) -> SetupIntentOut:
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
async def confirm_setup_intent(self, provider_setup_intent_id: str) -> SetupIntentOut:
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
async def get_setup_intent(self, provider_setup_intent_id: str) -> SetupIntentOut:
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
# --- SCA / 3DS resume ---
|
|
160
|
+
async def resume_intent_after_action(self, provider_intent_id: str) -> IntentOut:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
# --- Disputes ---
|
|
164
|
+
async def list_disputes(
|
|
165
|
+
self, *, status: str | None, limit: int, cursor: str | None
|
|
166
|
+
) -> tuple[list[DisputeOut], str | None]:
|
|
167
|
+
pass
|
|
168
|
+
|
|
169
|
+
async def get_dispute(self, provider_dispute_id: str) -> DisputeOut:
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
async def submit_dispute_evidence(self, provider_dispute_id: str, evidence: dict) -> DisputeOut:
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
# --- Balance & Payouts ---
|
|
176
|
+
async def get_balance_snapshot(self) -> BalanceSnapshotOut:
|
|
177
|
+
pass
|
|
178
|
+
|
|
179
|
+
async def list_payouts(
|
|
180
|
+
self, *, limit: int, cursor: str | None
|
|
181
|
+
) -> tuple[list[PayoutOut], str | None]:
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
async def get_payout(self, provider_payout_id: str) -> PayoutOut:
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
# --- Customers ---
|
|
188
|
+
async def list_customers(
|
|
189
|
+
self, *, provider: str | None, user_id: str | None, limit: int, cursor: str | None
|
|
190
|
+
) -> tuple[list[CustomerOut], str | None]:
|
|
191
|
+
"""Optional: if not implemented, the service will list from local DB."""
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
async def get_customer(self, provider_customer_id: str) -> Optional[CustomerOut]:
|
|
195
|
+
pass
|
|
196
|
+
|
|
197
|
+
# --- Products / Prices ---
|
|
198
|
+
async def get_product(self, provider_product_id: str) -> ProductOut:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
async def list_products(
|
|
202
|
+
self, *, active: bool | None, limit: int, cursor: str | None
|
|
203
|
+
) -> tuple[list[ProductOut], str | None]:
|
|
204
|
+
pass
|
|
205
|
+
|
|
206
|
+
async def update_product(self, provider_product_id: str, data: ProductUpdateIn) -> ProductOut:
|
|
207
|
+
pass
|
|
208
|
+
|
|
209
|
+
async def get_price(self, provider_price_id: str) -> PriceOut:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
async def list_prices(
|
|
213
|
+
self,
|
|
214
|
+
*,
|
|
215
|
+
provider_product_id: str | None,
|
|
216
|
+
active: bool | None,
|
|
217
|
+
limit: int,
|
|
218
|
+
cursor: str | None,
|
|
219
|
+
) -> tuple[list[PriceOut], str | None]:
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
async def update_price(self, provider_price_id: str, data: PriceUpdateIn) -> PriceOut:
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
# --- Subscriptions ---
|
|
226
|
+
async def get_subscription(self, provider_subscription_id: str) -> SubscriptionOut:
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
async def list_subscriptions(
|
|
230
|
+
self,
|
|
231
|
+
*,
|
|
232
|
+
customer_provider_id: str | None,
|
|
233
|
+
status: str | None,
|
|
234
|
+
limit: int,
|
|
235
|
+
cursor: str | None,
|
|
236
|
+
) -> tuple[list[SubscriptionOut], str | None]:
|
|
237
|
+
pass
|
|
238
|
+
|
|
239
|
+
# --- Payment Method (single + update) ---
|
|
240
|
+
async def get_payment_method(self, provider_method_id: str) -> PaymentMethodOut:
|
|
241
|
+
pass
|
|
242
|
+
|
|
243
|
+
async def update_payment_method(
|
|
244
|
+
self, provider_method_id: str, data: PaymentMethodUpdateIn
|
|
245
|
+
) -> PaymentMethodOut:
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
# --- Refunds list/get ---
|
|
249
|
+
async def list_refunds(
|
|
250
|
+
self, *, provider_payment_intent_id: str | None, limit: int, cursor: str | None
|
|
251
|
+
) -> tuple[list[RefundOut], str | None]:
|
|
252
|
+
pass
|
|
253
|
+
|
|
254
|
+
async def get_refund(self, provider_refund_id: str) -> RefundOut:
|
|
255
|
+
pass
|
|
256
|
+
|
|
257
|
+
# --- Invoice line items list ---
|
|
258
|
+
async def list_invoice_line_items(
|
|
259
|
+
self, provider_invoice_id: str, *, limit: int, cursor: str | None
|
|
260
|
+
) -> tuple[list[InvoiceLineItemOut], str | None]:
|
|
261
|
+
pass
|
|
262
|
+
|
|
263
|
+
# --- Usage records list/get ---
|
|
264
|
+
async def list_usage_records(
|
|
265
|
+
self, f: UsageRecordListFilter
|
|
266
|
+
) -> tuple[list[UsageRecordOut], str | None]:
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
async def get_usage_record(self, usage_record_id: str) -> UsageRecordOut:
|
|
270
|
+
pass
|