svc-infra 0.1.627__py3-none-any.whl → 0.1.629__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.

Potentially problematic release.


This version of svc-infra might be problematic. Click here for more details.

@@ -1172,6 +1172,9 @@ def ensure_problem_examples_mutator():
1172
1172
  continue
1173
1173
  if ic < 400:
1174
1174
  continue
1175
+ # Do not add content if response is a $ref; avoid creating siblings
1176
+ if "$ref" in resp:
1177
+ continue
1175
1178
  content = resp.setdefault("content", {})
1176
1179
  # prefer problem+json but also set application/json if present
1177
1180
  for mt in ("application/problem+json", "application/json"):
@@ -34,7 +34,12 @@ def add_probes(
34
34
  app.include_router(router)
35
35
 
36
36
 
37
- def add_maintenance_mode(app: FastAPI, *, env_var: str = "MAINTENANCE_MODE") -> None:
37
+ def add_maintenance_mode(
38
+ app: FastAPI,
39
+ *,
40
+ env_var: str = "MAINTENANCE_MODE",
41
+ exempt_prefixes: tuple[str, ...] | None = None,
42
+ ) -> None:
38
43
  """Enable a simple maintenance gate controlled by an env var.
39
44
 
40
45
  When MAINTENANCE_MODE is truthy, all non-GET requests return 503.
@@ -44,6 +49,9 @@ def add_maintenance_mode(app: FastAPI, *, env_var: str = "MAINTENANCE_MODE") ->
44
49
  async def _maintenance_gate(request: Request, call_next): # noqa: ANN001, ANN202
45
50
  flag = str(os.getenv(env_var, "")).lower() in {"1", "true", "yes", "on"}
46
51
  if flag and request.method not in {"GET", "HEAD", "OPTIONS"}:
52
+ path = request.scope.get("path", "")
53
+ if exempt_prefixes and any(path.startswith(p) for p in exempt_prefixes):
54
+ return await call_next(request)
47
55
  return JSONResponse({"detail": "maintenance"}, status_code=503)
48
56
  return await call_next(request)
49
57
 
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
3
4
  import os
4
5
  from importlib import import_module
5
6
  from typing import List, Optional
@@ -124,7 +125,11 @@ def cmd_current(
124
125
  ):
125
126
  """Display the current revision for each database."""
126
127
  apply_database_url(database_url)
127
- core_current(verbose=verbose)
128
+ result = core_current(verbose=verbose)
129
+ try:
130
+ typer.echo(json.dumps(result))
131
+ except Exception:
132
+ typer.echo(str(result))
128
133
 
129
134
 
130
135
  def cmd_history(
@@ -189,7 +194,7 @@ def cmd_setup_and_migrate(
189
194
  Async vs. sync is inferred from SQL_URL.
190
195
  """
191
196
  final_pkgs = _find_pkgs(with_payments, discover_packages)
192
- core_setup_and_migrate(
197
+ result = core_setup_and_migrate(
193
198
  overwrite_scaffold=overwrite_scaffold,
194
199
  create_db_if_missing=create_db_if_missing,
195
200
  create_followup_revision=create_followup_revision,
@@ -198,6 +203,12 @@ def cmd_setup_and_migrate(
198
203
  discover_packages=final_pkgs or None,
199
204
  database_url=database_url,
200
205
  )
206
+ # Echo a concise JSON result so tests and users can introspect outcome
207
+ try:
208
+ typer.echo(json.dumps(result))
209
+ except Exception:
210
+ # Fallback to plain string if not JSON-serializable for any reason
211
+ typer.echo(str(result))
201
212
 
202
213
 
203
214
  def register(app: typer.Typer) -> None:
@@ -205,7 +216,11 @@ def register(app: typer.Typer) -> None:
205
216
  app.command("init")(cmd_init)
206
217
  app.command("revision")(cmd_revision)
207
218
  app.command("upgrade")(cmd_upgrade)
208
- app.command("downgrade")(cmd_downgrade)
219
+ # Allow unknown options so users can pass "-1" like Alembic without Click treating it as an option
220
+ app.command(
221
+ "downgrade",
222
+ context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
223
+ )(cmd_downgrade)
209
224
  app.command("current")(cmd_current)
210
225
  app.command("history")(cmd_history)
211
226
  app.command("stamp")(cmd_stamp)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: svc-infra
3
- Version: 0.1.627
3
+ Version: 0.1.629
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
@@ -88,11 +88,11 @@ svc_infra/api/fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
88
88
  svc_infra/api/fastapi/openapi/apply.py,sha256=VAwRfcYSLCSKIpO1dp9okG1MXvkZuciU41jrSSuvUpI,1697
89
89
  svc_infra/api/fastapi/openapi/conventions.py,sha256=e6gUsFyfEGvz3KkUimjAWMfF7_fonMJ3IoGvQZjpvfs,7171
90
90
  svc_infra/api/fastapi/openapi/models.py,sha256=MmXMpPZQjZygajfIHaL4_3q0zluPtpRevsSyOIiE83Y,2562
91
- svc_infra/api/fastapi/openapi/mutators.py,sha256=0bSKVPw-lDA3L_vaPDhcM0rC7xKS-XNTzgR8hxxoM18,55266
91
+ svc_infra/api/fastapi/openapi/mutators.py,sha256=gzd7WbS_t6zrmFBJ_m1sxpzRNK6g_foHS5TqOED79Qw,55414
92
92
  svc_infra/api/fastapi/openapi/pipeline.py,sha256=GAf-qzwmWlYbrAlPirr8w89fEO4-kFrhCoeMj-7mE44,646
93
93
  svc_infra/api/fastapi/openapi/responses.py,sha256=pBUoJd0lltBkQBJACS1Zd1wd975gbw6dYyMEqyueRuw,1093
94
94
  svc_infra/api/fastapi/openapi/security.py,sha256=U78KMwgc7FilFPLbIE2f6xrp74hq6TDFXpUMGRyK_bg,1248
95
- svc_infra/api/fastapi/ops/add.py,sha256=39puYLuJdZuIBkpmMiHF6N8H4D-96TRtFdYidbzqndI,2311
95
+ svc_infra/api/fastapi/ops/add.py,sha256=ILMzFhYhfAaHEk6iqZQ15a2xgKAiZ0IKNuqWX-T8F04,2560
96
96
  svc_infra/api/fastapi/pagination.py,sha256=gQobCBb1dmyRjm62xYfkz-rBq_0hNyD0qEigYaLUky8,10972
97
97
  svc_infra/api/fastapi/paths/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  svc_infra/api/fastapi/paths/auth.py,sha256=hy9N0QFQnpv7dBOuHStui5eP9oIGHrawa0sADIVVD64,553
@@ -139,7 +139,7 @@ svc_infra/cli/cmds/db/nosql/mongo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
139
139
  svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py,sha256=s5oAlZ9bYndiRhtmi9gSbcJPvR82bwCGRbxAF_ziBx4,6125
140
140
  svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py,sha256=AR2sNt8Faxa6vAJ3MxGSWqLU54DMOL_r72hDtnEk4Pg,4253
141
141
  svc_infra/cli/cmds/db/sql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
- svc_infra/cli/cmds/db/sql/alembic_cmds.py,sha256=uCreHg69Zf6B5gbv9Dm39jCRk6q2KQy_05A-75IP0Fg,9650
142
+ svc_infra/cli/cmds/db/sql/alembic_cmds.py,sha256=C0TEZuwGmdb1WaaSbtjHf2RHAlxfuuacjLHfCi7ezxA,10237
143
143
  svc_infra/cli/cmds/db/sql/sql_export_cmds.py,sha256=YpkguUJFeFApMphVkhOJllTi25ejlsQaJarMe6vJD54,2685
144
144
  svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py,sha256=MKc_T_tY1Y_wQl7XTlq8GhYWMMI1q1_vcFZVPOEcNUg,4601
145
145
  svc_infra/cli/cmds/docs/docs_cmds.py,sha256=kvrBLeAvkv1lx_6TzvY_ciC9NJNBMNbmH0-wzA9LeHo,4501
@@ -325,7 +325,7 @@ svc_infra/webhooks/fastapi.py,sha256=BCNvGNxukf6dC2a4i-6en-PrjBGV19YvCWOot5lXWsA
325
325
  svc_infra/webhooks/router.py,sha256=6JvAVPMEth_xxHX-IsIOcyMgHX7g1H0OVxVXKLuMp9w,1596
326
326
  svc_infra/webhooks/service.py,sha256=hh-rw0otc00vipZ998XaV5mHsk0IDGYqon0FnhaGr60,2229
327
327
  svc_infra/webhooks/signing.py,sha256=NCwdZzmravUe7HVIK_uXK0qqf12FG-_MVsgPvOw6lsM,784
328
- svc_infra-0.1.627.dist-info/METADATA,sha256=gFcK2j_knbFCz4OneRWDtbNHdFo0B335tqD9RamcWA8,8748
329
- svc_infra-0.1.627.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
330
- svc_infra-0.1.627.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
331
- svc_infra-0.1.627.dist-info/RECORD,,
328
+ svc_infra-0.1.629.dist-info/METADATA,sha256=er59ifizb7n0wnHT4qtUIMkCC1l5kx5yol0WXlyw-cw,8748
329
+ svc_infra-0.1.629.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
330
+ svc_infra-0.1.629.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
331
+ svc_infra-0.1.629.dist-info/RECORD,,