cadwyn 4.2.2__py3-none-any.whl → 4.2.4__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 cadwyn might be problematic. Click here for more details.
- cadwyn/middleware.py +4 -4
- cadwyn/route_generation.py +1 -0
- cadwyn/schema_generation.py +1 -1
- cadwyn/structure/versions.py +29 -8
- {cadwyn-4.2.2.dist-info → cadwyn-4.2.4.dist-info}/METADATA +3 -4
- {cadwyn-4.2.2.dist-info → cadwyn-4.2.4.dist-info}/RECORD +9 -9
- {cadwyn-4.2.2.dist-info → cadwyn-4.2.4.dist-info}/LICENSE +0 -0
- {cadwyn-4.2.2.dist-info → cadwyn-4.2.4.dist-info}/WHEEL +0 -0
- {cadwyn-4.2.2.dist-info → cadwyn-4.2.4.dist-info}/entry_points.txt +0 -0
cadwyn/middleware.py
CHANGED
|
@@ -64,11 +64,11 @@ class HeaderVersioningMiddleware(BaseHTTPMiddleware):
|
|
|
64
64
|
request=request,
|
|
65
65
|
dependant=self.version_header_validation_dependant,
|
|
66
66
|
async_exit_stack=async_exit_stack,
|
|
67
|
+
embed_body_fields=False,
|
|
67
68
|
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
api_version = cast(date, values[self.api_version_header_name.replace("-", "_")])
|
|
69
|
+
if solved_result.errors:
|
|
70
|
+
return self.default_response_class(status_code=422, content=_normalize_errors(solved_result.errors))
|
|
71
|
+
api_version = cast(date, solved_result.values[self.api_version_header_name.replace("-", "_")])
|
|
72
72
|
self.api_version_var.set(api_version)
|
|
73
73
|
|
|
74
74
|
response = await call_next(request)
|
cadwyn/route_generation.py
CHANGED
|
@@ -376,6 +376,7 @@ def _add_data_migrations_to_route(
|
|
|
376
376
|
head_route,
|
|
377
377
|
dependant_for_request_migrations,
|
|
378
378
|
request_param_name=route.dependant.request_param_name,
|
|
379
|
+
background_tasks_param_name=route.dependant.background_tasks_param_name,
|
|
379
380
|
response_param_name=route.dependant.response_param_name,
|
|
380
381
|
)(route.endpoint)
|
|
381
382
|
route.dependant.call = route.endpoint
|
cadwyn/schema_generation.py
CHANGED
|
@@ -441,7 +441,7 @@ class _AnnotationTransformer:
|
|
|
441
441
|
def migrate_route_to_version(self, route: fastapi.routing.APIRoute, *, ignore_response_model: bool = False):
|
|
442
442
|
if route.response_model is not None and not ignore_response_model:
|
|
443
443
|
route.response_model = self.change_version_of_annotation(route.response_model)
|
|
444
|
-
route.response_field = fastapi.utils.
|
|
444
|
+
route.response_field = fastapi.utils.create_model_field(
|
|
445
445
|
name="Response_" + route.unique_id,
|
|
446
446
|
type_=route.response_model,
|
|
447
447
|
mode="serialization",
|
cadwyn/structure/versions.py
CHANGED
|
@@ -10,7 +10,7 @@ from datetime import date
|
|
|
10
10
|
from enum import Enum
|
|
11
11
|
from typing import Any, ClassVar, ParamSpec, TypeAlias, TypeVar
|
|
12
12
|
|
|
13
|
-
from fastapi import HTTPException, params
|
|
13
|
+
from fastapi import BackgroundTasks, HTTPException, params
|
|
14
14
|
from fastapi import Request as FastapiRequest
|
|
15
15
|
from fastapi import Response as FastapiResponse
|
|
16
16
|
from fastapi._compat import ModelField, _normalize_errors
|
|
@@ -350,7 +350,10 @@ class VersionBundle:
|
|
|
350
350
|
request_info: RequestInfo,
|
|
351
351
|
current_version: VersionDate,
|
|
352
352
|
head_route: APIRoute,
|
|
353
|
+
*,
|
|
353
354
|
exit_stack: AsyncExitStack,
|
|
355
|
+
embed_body_fields: bool,
|
|
356
|
+
background_tasks: BackgroundTasks | None,
|
|
354
357
|
) -> dict[str, Any]:
|
|
355
358
|
method = request.method
|
|
356
359
|
for v in reversed(self.versions):
|
|
@@ -367,19 +370,21 @@ class VersionBundle:
|
|
|
367
370
|
request.scope["headers"] = tuple((key.encode(), value.encode()) for key, value in request_info.headers.items())
|
|
368
371
|
del request._headers
|
|
369
372
|
# Remember this: if len(body_params) == 1, then route.body_schema == route.dependant.body_params[0]
|
|
370
|
-
|
|
373
|
+
result = await solve_dependencies(
|
|
371
374
|
request=request,
|
|
372
375
|
response=response,
|
|
373
376
|
dependant=head_dependant,
|
|
374
377
|
body=request_info.body,
|
|
375
378
|
dependency_overrides_provider=head_route.dependency_overrides_provider,
|
|
376
379
|
async_exit_stack=exit_stack,
|
|
380
|
+
embed_body_fields=embed_body_fields,
|
|
381
|
+
background_tasks=background_tasks,
|
|
377
382
|
)
|
|
378
|
-
if errors:
|
|
383
|
+
if result.errors:
|
|
379
384
|
raise CadwynHeadRequestValidationError(
|
|
380
|
-
_normalize_errors(errors), body=request_info.body, version=current_version
|
|
385
|
+
_normalize_errors(result.errors), body=request_info.body, version=current_version
|
|
381
386
|
)
|
|
382
|
-
return
|
|
387
|
+
return result.values
|
|
383
388
|
|
|
384
389
|
def _migrate_response(
|
|
385
390
|
self,
|
|
@@ -431,6 +436,7 @@ class VersionBundle:
|
|
|
431
436
|
dependant_for_request_migrations: Dependant,
|
|
432
437
|
*,
|
|
433
438
|
request_param_name: str,
|
|
439
|
+
background_tasks_param_name: str | None,
|
|
434
440
|
response_param_name: str,
|
|
435
441
|
) -> Callable[[Endpoint[_P, _R]], Endpoint[_P, _R]]:
|
|
436
442
|
def wrapper(endpoint: Endpoint[_P, _R]) -> Endpoint[_P, _R]:
|
|
@@ -438,6 +444,10 @@ class VersionBundle:
|
|
|
438
444
|
async def decorator(*args: Any, **kwargs: Any) -> _R:
|
|
439
445
|
request_param: FastapiRequest = kwargs[request_param_name]
|
|
440
446
|
response_param: FastapiResponse = kwargs[response_param_name]
|
|
447
|
+
background_tasks: BackgroundTasks | None = kwargs.get(
|
|
448
|
+
background_tasks_param_name, # pyright: ignore[reportArgumentType, reportCallIssue]
|
|
449
|
+
None,
|
|
450
|
+
)
|
|
441
451
|
method = request_param.method
|
|
442
452
|
response = Sentinel
|
|
443
453
|
async with AsyncExitStack() as exit_stack:
|
|
@@ -452,7 +462,9 @@ class VersionBundle:
|
|
|
452
462
|
response_param,
|
|
453
463
|
route,
|
|
454
464
|
head_route,
|
|
455
|
-
exit_stack,
|
|
465
|
+
exit_stack=exit_stack,
|
|
466
|
+
embed_body_fields=route._embed_body_fields,
|
|
467
|
+
background_tasks=background_tasks,
|
|
456
468
|
)
|
|
457
469
|
|
|
458
470
|
response = await self._convert_endpoint_response_to_version(
|
|
@@ -524,10 +536,14 @@ class VersionBundle:
|
|
|
524
536
|
if isinstance(response_or_response_body, StreamingResponse | FileResponse):
|
|
525
537
|
body = None
|
|
526
538
|
elif response_or_response_body.body:
|
|
527
|
-
if isinstance(response_or_response_body, JSONResponse) or raised_exception is not None
|
|
539
|
+
if (isinstance(response_or_response_body, JSONResponse) or raised_exception is not None) and isinstance(
|
|
540
|
+
response_or_response_body.body, str | bytes
|
|
541
|
+
):
|
|
528
542
|
body = json.loads(response_or_response_body.body)
|
|
529
|
-
|
|
543
|
+
elif isinstance(response_or_response_body.body, bytes):
|
|
530
544
|
body = response_or_response_body.body.decode(response_or_response_body.charset)
|
|
545
|
+
else: # pragma: no cover # I don't see a good use case here yet
|
|
546
|
+
body = response_or_response_body.body
|
|
531
547
|
else:
|
|
532
548
|
body = None
|
|
533
549
|
# TODO (https://github.com/zmievsa/cadwyn/issues/51): Only do this if there are migrations
|
|
@@ -614,7 +630,10 @@ class VersionBundle:
|
|
|
614
630
|
response: FastapiResponse,
|
|
615
631
|
route: APIRoute,
|
|
616
632
|
head_route: APIRoute,
|
|
633
|
+
*,
|
|
617
634
|
exit_stack: AsyncExitStack,
|
|
635
|
+
embed_body_fields: bool,
|
|
636
|
+
background_tasks: BackgroundTasks | None,
|
|
618
637
|
) -> dict[str, Any]:
|
|
619
638
|
request: FastapiRequest = kwargs[request_param_name]
|
|
620
639
|
if request_param_name == _CADWYN_REQUEST_PARAM_NAME:
|
|
@@ -655,6 +674,8 @@ class VersionBundle:
|
|
|
655
674
|
api_version,
|
|
656
675
|
head_route,
|
|
657
676
|
exit_stack=exit_stack,
|
|
677
|
+
embed_body_fields=embed_body_fields,
|
|
678
|
+
background_tasks=background_tasks,
|
|
658
679
|
)
|
|
659
680
|
# Because we re-added it into our kwargs when we did solve_dependencies
|
|
660
681
|
if _CADWYN_REQUEST_PARAM_NAME in new_kwargs:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cadwyn
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.4
|
|
4
4
|
Summary: Production-ready community-driven modern Stripe-like API versioning in FastAPI
|
|
5
5
|
Home-page: https://github.com/zmievsa/cadwyn
|
|
6
6
|
License: MIT
|
|
@@ -31,14 +31,13 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
31
31
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
32
32
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
33
33
|
Classifier: Typing :: Typed
|
|
34
|
-
Provides-Extra: cli
|
|
35
34
|
Requires-Dist: backports-strenum (>=1.3.1,<2.0.0) ; python_version < "3.11"
|
|
36
|
-
Requires-Dist: fastapi (>=0.
|
|
35
|
+
Requires-Dist: fastapi[standard] (>=0.112.3)
|
|
37
36
|
Requires-Dist: issubclass (>=0.1.2,<0.2.0)
|
|
38
37
|
Requires-Dist: jinja2 (>=3.1.2)
|
|
39
38
|
Requires-Dist: pydantic (>=2.0.0)
|
|
40
39
|
Requires-Dist: starlette (>=0.30.0)
|
|
41
|
-
Requires-Dist: typer (>=0.7.0)
|
|
40
|
+
Requires-Dist: typer (>=0.7.0)
|
|
42
41
|
Requires-Dist: typing-extensions
|
|
43
42
|
Project-URL: Documentation, https://docs.cadwyn.dev
|
|
44
43
|
Project-URL: Repository, https://github.com/zmievsa/cadwyn
|
|
@@ -7,11 +7,11 @@ cadwyn/_utils.py,sha256=GK9w_qzyOI_o6UaGVfwLLYhnJFMzXistoYI9fq2E9dE,1159
|
|
|
7
7
|
cadwyn/applications.py,sha256=9gObB244eDTMi9-Nah3F5ErB2bSABkeGHWO7lfBcivM,16013
|
|
8
8
|
cadwyn/changelogs.py,sha256=SdrdAKQ01mpzs-EN_zg-D0TY7wxsibjRjLMhGcI4q80,20066
|
|
9
9
|
cadwyn/exceptions.py,sha256=VlJKRmEGfFTDtHbOWc8kXK4yMi2N172K684Y2UIV8rI,1832
|
|
10
|
-
cadwyn/middleware.py,sha256=
|
|
10
|
+
cadwyn/middleware.py,sha256=kUZK2dmoricMbv6knPCIHpXEInX2670XIwAj0v_XQxk,3408
|
|
11
11
|
cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
cadwyn/route_generation.py,sha256
|
|
12
|
+
cadwyn/route_generation.py,sha256=npAWxhr38_NNZOvXriPt_StdzR4WeL5Xwv505e9Gn9s,22953
|
|
13
13
|
cadwyn/routing.py,sha256=9AHSojmuLgUAQlLMIqXz-ViZ9n-fljgOsn7oxha7PjM,7341
|
|
14
|
-
cadwyn/schema_generation.py,sha256=
|
|
14
|
+
cadwyn/schema_generation.py,sha256=1eJ--nyG8onUROWegCmQQWJ4iJEu1MrTt-8bnLIQyeQ,39992
|
|
15
15
|
cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
|
|
17
17
|
cadwyn/structure/__init__.py,sha256=vej7TdTMSOg8U8Wk7GTNdA4rc6loA9083FWaTg4jAaY,655
|
|
@@ -20,9 +20,9 @@ cadwyn/structure/data.py,sha256=1ALPhBBCE_t4GrxM0Fa3hQ-jkORJgeWNySnZ42bsi0g,7382
|
|
|
20
20
|
cadwyn/structure/endpoints.py,sha256=9FFnbqPM9v0CP6J6tGhMNKVvWqA9u3ZjI2Fannr2Rl0,5933
|
|
21
21
|
cadwyn/structure/enums.py,sha256=bZL-iUOUFi9ZYlMZJw-tAix2yrgCp3gH3N2gwO44LUU,1043
|
|
22
22
|
cadwyn/structure/schemas.py,sha256=D0BD1D3v9MRdVWchU9JM2zHd0dvB0UgXHDGFCe5aQZc,8209
|
|
23
|
-
cadwyn/structure/versions.py,sha256=
|
|
24
|
-
cadwyn-4.2.
|
|
25
|
-
cadwyn-4.2.
|
|
26
|
-
cadwyn-4.2.
|
|
27
|
-
cadwyn-4.2.
|
|
28
|
-
cadwyn-4.2.
|
|
23
|
+
cadwyn/structure/versions.py,sha256=2qe7xFYNdzdWmCZhkf4_zJ7lF0XdtyM1wq6xQ9omb_c,33655
|
|
24
|
+
cadwyn-4.2.4.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
|
|
25
|
+
cadwyn-4.2.4.dist-info/METADATA,sha256=p4VPoo3GACrQLJKtvuf4Zw2J2M9JJ3aqn8Faai49I08,4393
|
|
26
|
+
cadwyn-4.2.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
27
|
+
cadwyn-4.2.4.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
|
|
28
|
+
cadwyn-4.2.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|