Skip to content

Commit 89e3a46

Browse files
authored
Add support for fastapi>=0.128.0 (#317)
1 parent e631a13 commit 89e3a46

File tree

4 files changed

+83
-66
lines changed

4 files changed

+83
-66
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ Please follow [the Keep a Changelog standard](https://keepachangelog.com/en/1.0.
55

66
## [Unreleased]
77

8+
## [6.0.0]
9+
10+
### Fixed
11+
12+
- Support for FastAPI>=0.128.0+
13+
14+
### Removed
15+
16+
- Support for FastAPI < 0.128.0 and Pydantic v1
17+
818
## [5.6.2]
919

1020
### Fixed

cadwyn/structure/versions.py

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
from fastapi import BackgroundTasks, HTTPException, params
1515
from fastapi import Request as FastapiRequest
1616
from fastapi import Response as FastapiResponse
17-
from fastapi._compat import ModelField, _normalize_errors
17+
from fastapi._compat import ModelField
1818
from fastapi.concurrency import run_in_threadpool
1919
from fastapi.dependencies.models import Dependant
2020
from fastapi.dependencies.utils import solve_dependencies
2121
from fastapi.exceptions import RequestValidationError
2222
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
23-
from fastapi.routing import APIRoute, _prepare_response_content
23+
from fastapi.routing import APIRoute
2424
from pydantic import BaseModel
2525
from pydantic_core import PydanticUndefined
2626
from starlette._utils import is_async_callable
@@ -60,47 +60,45 @@
6060
]
6161

6262

63-
def _normalize_response_content(
64-
content: Any,
63+
def _prepare_response_content(
64+
res: Any,
6565
*,
66-
exclude_unset: bool = False,
66+
exclude_unset: bool,
6767
exclude_defaults: bool = False,
6868
exclude_none: bool = False,
6969
) -> Any:
70-
"""Convert Pydantic models to dicts for FastAPI >= 0.126.0 compatibility.
70+
"""Serialize Pydantic models to dicts for response processing.
7171
72-
In FastAPI >= 0.126.0, _prepare_response_content may return Pydantic model
73-
instances instead of dicts. This function ensures the content is always
74-
a dict/list/primitive for user migrations to work correctly.
72+
It is much easier to alter dicts and lists than Pydantic models in request/response migrations
7573
"""
76-
if isinstance(content, BaseModel):
77-
return content.model_dump(
74+
if isinstance(res, BaseModel):
75+
return res.model_dump(
7876
by_alias=True,
7977
exclude_unset=exclude_unset,
8078
exclude_defaults=exclude_defaults,
8179
exclude_none=exclude_none,
8280
)
83-
elif isinstance(content, list):
81+
elif isinstance(res, list):
8482
return [
85-
_normalize_response_content(
83+
_prepare_response_content(
8684
item,
8785
exclude_unset=exclude_unset,
8886
exclude_defaults=exclude_defaults,
8987
exclude_none=exclude_none,
9088
)
91-
for item in content
89+
for item in res
9290
]
93-
elif isinstance(content, dict):
91+
elif isinstance(res, dict):
9492
return {
95-
k: _normalize_response_content(
93+
k: _prepare_response_content(
9694
v,
9795
exclude_unset=exclude_unset,
9896
exclude_defaults=exclude_defaults,
9997
exclude_none=exclude_none,
10098
)
101-
for k, v in content.items()
99+
for k, v in res.items()
102100
}
103-
return content
101+
return res
104102

105103

106104
APIVersionVarType: TypeAlias = Union[ContextVar[Union[VersionType, None]], ContextVar[VersionType]]
@@ -445,9 +443,7 @@ async def _migrate_request(
445443
background_tasks=background_tasks,
446444
)
447445
if result.errors:
448-
raise CadwynHeadRequestValidationError(
449-
_normalize_errors(result.errors), body=request_info.body, version=current_version
450-
)
446+
raise CadwynHeadRequestValidationError(result.errors, body=request_info.body, version=current_version)
451447
return result.values
452448

453449
def _migrate_response(
@@ -610,16 +606,10 @@ async def _convert_endpoint_response_to_version( # noqa: C901
610606
else:
611607
status_code = 200
612608
fastapi_response_dependency.status_code = status_code
613-
prepared_content = _prepare_response_content(
614-
response_or_response_body,
615-
exclude_unset=head_route.response_model_exclude_unset,
616-
exclude_defaults=head_route.response_model_exclude_defaults,
617-
exclude_none=head_route.response_model_exclude_none,
618-
)
619609
response_info = ResponseInfo(
620610
fastapi_response_dependency,
621-
_normalize_response_content(
622-
prepared_content,
611+
_prepare_response_content(
612+
response_or_response_body,
623613
exclude_unset=head_route.response_model_exclude_unset,
624614
exclude_defaults=head_route.response_model_exclude_defaults,
625615
exclude_none=head_route.response_model_exclude_none,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "cadwyn"
3-
version = "5.6.2"
3+
version = "6.0.0"
44
description = "Production-ready community-driven modern Stripe-like API versioning in FastAPI"
55
authors = [{ name = "Stanislav Zmiev", email = "zmievsa@gmail.com" }]
66
license = "MIT"

0 commit comments

Comments
 (0)