import dataclasses
import inspect
import sys
+import warnings
from collections.abc import Coroutine, Mapping, Sequence
from contextlib import AsyncExitStack, contextmanager
from copy import copy, deepcopy
)
continue
assert param_details.field is not None
+ if isinstance(param_details.field, may_v1.ModelField):
+ warnings.warn(
+ "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
+ f" Please update the param {param_name}: {param_details.type_annotation!r}.",
+ category=DeprecationWarning,
+ stacklevel=5,
+ )
if isinstance(
param_details.field.field_info, (params.Body, temp_pydantic_v1_params.Body)
):
import functools
import inspect
import json
+import warnings
from collections.abc import (
AsyncIterator,
Awaitable,
_get_model_config,
_model_dump,
_normalize_errors,
+ annotation_is_pydantic_v1,
lenient_issubclass,
may_v1,
)
f"Status code {status_code} must not have a response body"
)
response_name = "Response_" + self.unique_id
+ if annotation_is_pydantic_v1(self.response_model):
+ warnings.warn(
+ "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
+ f" Please update the response model {self.response_model!r}.",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
self.response_field = create_model_field(
name=response_name,
type_=self.response_model,
f"Status code {additional_status_code} must not have a response body"
)
response_name = f"Response_{additional_status_code}_{self.unique_id}"
+ if annotation_is_pydantic_v1(model):
+ warnings.warn(
+ "pydantic.v1 is deprecated and will soon stop being supported by FastAPI."
+ f" In responses={{}}, please update {model}.",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
response_field = create_model_field(
name=response_name, type_=model, mode="serialization"
)
import json
import sys
+import warnings
from collections.abc import Iterator
from typing import Annotated, Any
app = FastAPI()
- @app.post("/sync/validated", response_model=ItemOut)
- def sync_validated(item: ItemIn, dep: Annotated[int, Depends(dep_b)]):
- return ItemOut(name=item.name, value=item.value, dep=dep)
-
- @app.get("/sync/dict-no-response-model")
- def sync_dict_no_response_model():
- return {"name": "foo", "value": 123}
-
- @app.get("/sync/dict-with-response-model", response_model=ItemOut)
- def sync_dict_with_response_model(
- dep: Annotated[int, Depends(dep_b)],
- ):
- return {"name": "foo", "value": 123, "dep": dep}
-
- @app.get("/sync/model-no-response-model")
- def sync_model_no_response_model(dep: Annotated[int, Depends(dep_b)]):
- return ItemOut(name="foo", value=123, dep=dep)
-
- @app.get("/sync/model-with-response-model", response_model=ItemOut)
- def sync_model_with_response_model(dep: Annotated[int, Depends(dep_b)]):
- return ItemOut(name="foo", value=123, dep=dep)
-
- @app.post("/async/validated", response_model=ItemOut)
- async def async_validated(
- item: ItemIn,
- dep: Annotated[int, Depends(dep_b)],
- ):
- return ItemOut(name=item.name, value=item.value, dep=dep)
-
- @app.post("/sync/large-receive")
- def sync_large_receive(payload: LargeIn):
- return {"received": len(payload.items)}
-
- @app.post("/async/large-receive")
- async def async_large_receive(payload: LargeIn):
- return {"received": len(payload.items)}
-
- @app.get("/sync/large-dict-no-response-model")
- def sync_large_dict_no_response_model():
- return LARGE_PAYLOAD
-
- @app.get("/sync/large-dict-with-response-model", response_model=LargeOut)
- def sync_large_dict_with_response_model():
- return LARGE_PAYLOAD
-
- @app.get("/sync/large-model-no-response-model")
- def sync_large_model_no_response_model():
- return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
-
- @app.get("/sync/large-model-with-response-model", response_model=LargeOut)
- def sync_large_model_with_response_model():
- return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
-
- @app.get("/async/large-dict-no-response-model")
- async def async_large_dict_no_response_model():
- return LARGE_PAYLOAD
-
- @app.get("/async/large-dict-with-response-model", response_model=LargeOut)
- async def async_large_dict_with_response_model():
- return LARGE_PAYLOAD
-
- @app.get("/async/large-model-no-response-model")
- async def async_large_model_no_response_model():
- return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
-
- @app.get("/async/large-model-with-response-model", response_model=LargeOut)
- async def async_large_model_with_response_model():
- return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
-
- @app.get("/async/dict-no-response-model")
- async def async_dict_no_response_model():
- return {"name": "foo", "value": 123}
-
- @app.get("/async/dict-with-response-model", response_model=ItemOut)
- async def async_dict_with_response_model(
- dep: Annotated[int, Depends(dep_b)],
- ):
- return {"name": "foo", "value": 123, "dep": dep}
-
- @app.get("/async/model-no-response-model")
- async def async_model_no_response_model(
- dep: Annotated[int, Depends(dep_b)],
- ):
- return ItemOut(name="foo", value=123, dep=dep)
-
- @app.get("/async/model-with-response-model", response_model=ItemOut)
- async def async_model_with_response_model(
- dep: Annotated[int, Depends(dep_b)],
- ):
- return ItemOut(name="foo", value=123, dep=dep)
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+
+ @app.post("/sync/validated", response_model=ItemOut)
+ def sync_validated(item: ItemIn, dep: Annotated[int, Depends(dep_b)]):
+ return ItemOut(name=item.name, value=item.value, dep=dep)
+
+ @app.get("/sync/dict-no-response-model")
+ def sync_dict_no_response_model():
+ return {"name": "foo", "value": 123}
+
+ @app.get("/sync/dict-with-response-model", response_model=ItemOut)
+ def sync_dict_with_response_model(
+ dep: Annotated[int, Depends(dep_b)],
+ ):
+ return {"name": "foo", "value": 123, "dep": dep}
+
+ @app.get("/sync/model-no-response-model")
+ def sync_model_no_response_model(dep: Annotated[int, Depends(dep_b)]):
+ return ItemOut(name="foo", value=123, dep=dep)
+
+ @app.get("/sync/model-with-response-model", response_model=ItemOut)
+ def sync_model_with_response_model(dep: Annotated[int, Depends(dep_b)]):
+ return ItemOut(name="foo", value=123, dep=dep)
+
+ @app.post("/async/validated", response_model=ItemOut)
+ async def async_validated(
+ item: ItemIn,
+ dep: Annotated[int, Depends(dep_b)],
+ ):
+ return ItemOut(name=item.name, value=item.value, dep=dep)
+
+ @app.post("/sync/large-receive")
+ def sync_large_receive(payload: LargeIn):
+ return {"received": len(payload.items)}
+
+ @app.post("/async/large-receive")
+ async def async_large_receive(payload: LargeIn):
+ return {"received": len(payload.items)}
+
+ @app.get("/sync/large-dict-no-response-model")
+ def sync_large_dict_no_response_model():
+ return LARGE_PAYLOAD
+
+ @app.get("/sync/large-dict-with-response-model", response_model=LargeOut)
+ def sync_large_dict_with_response_model():
+ return LARGE_PAYLOAD
+
+ @app.get("/sync/large-model-no-response-model")
+ def sync_large_model_no_response_model():
+ return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
+
+ @app.get("/sync/large-model-with-response-model", response_model=LargeOut)
+ def sync_large_model_with_response_model():
+ return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
+
+ @app.get("/async/large-dict-no-response-model")
+ async def async_large_dict_no_response_model():
+ return LARGE_PAYLOAD
+
+ @app.get("/async/large-dict-with-response-model", response_model=LargeOut)
+ async def async_large_dict_with_response_model():
+ return LARGE_PAYLOAD
+
+ @app.get("/async/large-model-no-response-model")
+ async def async_large_model_no_response_model():
+ return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
+
+ @app.get("/async/large-model-with-response-model", response_model=LargeOut)
+ async def async_large_model_with_response_model():
+ return LargeOut(items=LARGE_ITEMS, metadata=LARGE_METADATA)
+
+ @app.get("/async/dict-no-response-model")
+ async def async_dict_no_response_model():
+ return {"name": "foo", "value": 123}
+
+ @app.get("/async/dict-with-response-model", response_model=ItemOut)
+ async def async_dict_with_response_model(
+ dep: Annotated[int, Depends(dep_b)],
+ ):
+ return {"name": "foo", "value": 123, "dep": dep}
+
+ @app.get("/async/model-no-response-model")
+ async def async_model_no_response_model(
+ dep: Annotated[int, Depends(dep_b)],
+ ):
+ return ItemOut(name="foo", value=123, dep=dep)
+
+ @app.get("/async/model-with-response-model", response_model=ItemOut)
+ async def async_model_with_response_model(
+ dep: Annotated[int, Depends(dep_b)],
+ ):
+ return ItemOut(name="foo", value=123, dep=dep)
return app
import sys
+import warnings
from typing import Optional
import pytest
app = FastAPI()
-
-@app.get("/items/{item_id}")
-def get_item_with_path(
- item_id: Annotated[int, Path(title="The ID of the item", ge=1, le=1000)],
-):
- return {"item_id": item_id}
-
-
-@app.get("/items/")
-def get_items_with_query(
- q: Annotated[
- Optional[str], Query(min_length=3, max_length=50, pattern="^[a-zA-Z0-9 ]+$")
- ] = None,
- skip: Annotated[int, Query(ge=0)] = 0,
- limit: Annotated[int, Query(ge=1, le=100, examples=[5])] = 10,
-):
- return {"q": q, "skip": skip, "limit": limit}
-
-
-@app.get("/users/")
-def get_user_with_header(
- x_custom: Annotated[Optional[str], Header()] = None,
- x_token: Annotated[Optional[str], Header(convert_underscores=True)] = None,
-):
- return {"x_custom": x_custom, "x_token": x_token}
-
-
-@app.get("/cookies/")
-def get_cookies(
- session_id: Annotated[Optional[str], Cookie()] = None,
- tracking_id: Annotated[Optional[str], Cookie(min_length=10)] = None,
-):
- return {"session_id": session_id, "tracking_id": tracking_id}
-
-
-@app.post("/items/")
-def create_item(
- item: Annotated[
- Item,
- Body(examples=[{"name": "Foo", "price": 35.4, "description": "The Foo item"}]),
- ],
-):
- return {"item": item}
-
-
-@app.post("/items-embed/")
-def create_item_embed(
- item: Annotated[Item, Body(embed=True)],
-):
- return {"item": item}
-
-
-@app.put("/items/{item_id}")
-def update_item(
- item_id: Annotated[int, Path(ge=1)],
- item: Annotated[Item, Body()],
- importance: Annotated[int, Body(gt=0, le=10)],
-):
- return {"item": item, "importance": importance}
-
-
-@app.post("/form-data/")
-def submit_form(
- username: Annotated[str, Form(min_length=3, max_length=50)],
- password: Annotated[str, Form(min_length=8)],
- email: Annotated[Optional[str], Form()] = None,
-):
- return {"username": username, "password": password, "email": email}
-
-
-@app.post("/upload/")
-def upload_file(
- file: Annotated[bytes, File()],
- description: Annotated[Optional[str], Form()] = None,
-):
- return {"file_size": len(file), "description": description}
-
-
-@app.post("/upload-multiple/")
-def upload_multiple_files(
- files: Annotated[list[bytes], File()],
- note: Annotated[str, Form()] = "",
-):
- return {
- "file_count": len(files),
- "total_size": sum(len(f) for f in files),
- "note": note,
- }
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.get("/items/{item_id}")
+ def get_item_with_path(
+ item_id: Annotated[int, Path(title="The ID of the item", ge=1, le=1000)],
+ ):
+ return {"item_id": item_id}
+
+ @app.get("/items/")
+ def get_items_with_query(
+ q: Annotated[
+ Optional[str],
+ Query(min_length=3, max_length=50, pattern="^[a-zA-Z0-9 ]+$"),
+ ] = None,
+ skip: Annotated[int, Query(ge=0)] = 0,
+ limit: Annotated[int, Query(ge=1, le=100, examples=[5])] = 10,
+ ):
+ return {"q": q, "skip": skip, "limit": limit}
+
+ @app.get("/users/")
+ def get_user_with_header(
+ x_custom: Annotated[Optional[str], Header()] = None,
+ x_token: Annotated[Optional[str], Header(convert_underscores=True)] = None,
+ ):
+ return {"x_custom": x_custom, "x_token": x_token}
+
+ @app.get("/cookies/")
+ def get_cookies(
+ session_id: Annotated[Optional[str], Cookie()] = None,
+ tracking_id: Annotated[Optional[str], Cookie(min_length=10)] = None,
+ ):
+ return {"session_id": session_id, "tracking_id": tracking_id}
+
+ @app.post("/items/")
+ def create_item(
+ item: Annotated[
+ Item,
+ Body(
+ examples=[{"name": "Foo", "price": 35.4, "description": "The Foo item"}]
+ ),
+ ],
+ ):
+ return {"item": item}
+
+ @app.post("/items-embed/")
+ def create_item_embed(
+ item: Annotated[Item, Body(embed=True)],
+ ):
+ return {"item": item}
+
+ @app.put("/items/{item_id}")
+ def update_item(
+ item_id: Annotated[int, Path(ge=1)],
+ item: Annotated[Item, Body()],
+ importance: Annotated[int, Body(gt=0, le=10)],
+ ):
+ return {"item": item, "importance": importance}
+
+ @app.post("/form-data/")
+ def submit_form(
+ username: Annotated[str, Form(min_length=3, max_length=50)],
+ password: Annotated[str, Form(min_length=8)],
+ email: Annotated[Optional[str], Form()] = None,
+ ):
+ return {"username": username, "password": password, "email": email}
+
+ @app.post("/upload/")
+ def upload_file(
+ file: Annotated[bytes, File()],
+ description: Annotated[Optional[str], Form()] = None,
+ ):
+ return {"file_size": len(file), "description": description}
+
+ @app.post("/upload-multiple/")
+ def upload_multiple_files(
+ files: Annotated[list[bytes], File()],
+ note: Annotated[str, Form()] = "",
+ ):
+ return {
+ "file_count": len(files),
+ "total_size": sum(len(f) for f in files),
+ "note": note,
+ }
client = TestClient(app)
# Cookie parameter tests
def test_cookie_params():
- with TestClient(app) as client:
- client.cookies.set("session_id", "abc123")
- client.cookies.set("tracking_id", "1234567890abcdef")
- response = client.get("/cookies/")
+ with TestClient(app) as test_client:
+ test_client.cookies.set("session_id", "abc123")
+ test_client.cookies.set("tracking_id", "1234567890abcdef")
+ response = test_client.get("/cookies/")
assert response.status_code == 200
assert response.json() == {
"session_id": "abc123",
def test_cookie_tracking_id_too_short():
- with TestClient(app) as client:
- client.cookies.set("tracking_id", "short")
- response = client.get("/cookies/")
+ with TestClient(app) as test_client:
+ test_client.cookies.set("tracking_id", "short")
+ response = test_client.get("/cookies/")
assert response.status_code == 422
assert response.json() == snapshot(
{
+import warnings
from datetime import datetime, timezone
from fastapi import FastAPI
app = FastAPI()
model = ModelWithDatetimeField(dt_field=datetime(2019, 1, 1, 8))
- @app.get("/model", response_model=ModelWithDatetimeField)
- def get_model():
- return model
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.get("/model", response_model=ModelWithDatetimeField)
+ def get_model():
+ return model
client = TestClient(app)
with client:
+import warnings
from typing import Optional
from fastapi import Depends, FastAPI
return ModelC(username="test-user", password="test-password")
-@app.get("/model/{name}", response_model=ModelA)
-async def get_model_a(name: str, model_c=Depends(get_model_c)):
- return {
- "name": name,
- "description": "model-a-desc",
- "model_b": model_c,
- "tags": {"key1": "value1", "key2": "value2"},
- }
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.get("/model/{name}", response_model=ModelA)
+ async def get_model_a(name: str, model_c=Depends(get_model_c)):
+ return {
+ "name": name,
+ "description": "model-a-desc",
+ "model_b": model_c,
+ "tags": {"key1": "value1", "key2": "value2"},
+ }
+import warnings
+
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
- @app.get("/facilities/{facility_id}")
- def get_facility(facility_id: str) -> Facility:
- return Facility(
- id=facility_id,
- address=Address(line_1="123 Main St", city="Anytown", state_province="CA"),
- )
+ if request.param == "pydantic-v1":
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.get("/facilities/{facility_id}")
+ def get_facility(facility_id: str) -> Facility:
+ return Facility(
+ id=facility_id,
+ address=Address(
+ line_1="123 Main St", city="Anytown", state_province="CA"
+ ),
+ )
+ else:
+
+ @app.get("/facilities/{facility_id}")
+ def get_facility(facility_id: str) -> Facility:
+ return Facility(
+ id=facility_id,
+ address=Address(
+ line_1="123 Main St", city="Anytown", state_province="CA"
+ ),
+ )
client = TestClient(app)
return client
--- /dev/null
+import sys
+
+import pytest
+
+from tests.utils import skip_module_if_py_gte_314
+
+if sys.version_info >= (3, 14):
+ skip_module_if_py_gte_314()
+
+from fastapi import FastAPI
+from fastapi._compat.v1 import BaseModel
+from fastapi.testclient import TestClient
+
+
+def test_warns_pydantic_v1_model_in_endpoint_param() -> None:
+ class ParamModelV1(BaseModel):
+ name: str
+
+ app = FastAPI()
+
+ with pytest.warns(
+ DeprecationWarning,
+ match=r"pydantic\.v1 is deprecated.*Please update the param data:",
+ ):
+
+ @app.post("/param")
+ def endpoint(data: ParamModelV1):
+ return data
+
+ client = TestClient(app)
+ response = client.post("/param", json={"name": "test"})
+ assert response.status_code == 200, response.text
+ assert response.json() == {"name": "test"}
+
+
+def test_warns_pydantic_v1_model_in_return_type() -> None:
+ class ReturnModelV1(BaseModel):
+ name: str
+
+ app = FastAPI()
+
+ with pytest.warns(
+ DeprecationWarning,
+ match=r"pydantic\.v1 is deprecated.*Please update the response model",
+ ):
+
+ @app.get("/return")
+ def endpoint() -> ReturnModelV1:
+ return ReturnModelV1(name="test")
+
+ client = TestClient(app)
+ response = client.get("/return")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"name": "test"}
+
+
+def test_warns_pydantic_v1_model_in_response_model() -> None:
+ class ResponseModelV1(BaseModel):
+ name: str
+
+ app = FastAPI()
+
+ with pytest.warns(
+ DeprecationWarning,
+ match=r"pydantic\.v1 is deprecated.*Please update the response model",
+ ):
+
+ @app.get("/response-model", response_model=ResponseModelV1)
+ def endpoint():
+ return {"name": "test"}
+
+ client = TestClient(app)
+ response = client.get("/response-model")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"name": "test"}
+
+
+def test_warns_pydantic_v1_model_in_additional_responses_model() -> None:
+ class ErrorModelV1(BaseModel):
+ detail: str
+
+ app = FastAPI()
+
+ with pytest.warns(
+ DeprecationWarning,
+ match=r"pydantic\.v1 is deprecated.*In responses=\{\}, please update",
+ ):
+
+ @app.get(
+ "/responses", response_model=None, responses={400: {"model": ErrorModelV1}}
+ )
+ def endpoint():
+ return {"ok": True}
+
+ client = TestClient(app)
+ response = client.get("/responses")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"ok": True}
import sys
+import warnings
from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314
app = FastAPI()
-
-@app.post("/simple-model")
-def handle_simple_model(data: SubItem) -> SubItem:
- return data
-
-
-@app.post("/simple-model-filter", response_model=SubItem)
-def handle_simple_model_filter(data: SubItem) -> Any:
- extended_data = data.dict()
- extended_data.update({"secret_price": 42})
- return extended_data
-
-
-@app.post("/item")
-def handle_item(data: Item) -> Item:
- return data
-
-
-@app.post("/item-filter", response_model=Item)
-def handle_item_filter(data: Item) -> Any:
- extended_data = data.dict()
- extended_data.update({"secret_data": "classified", "internal_id": 12345})
- extended_data["sub"].update({"internal_id": 67890})
- return extended_data
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.post("/simple-model")
+ def handle_simple_model(data: SubItem) -> SubItem:
+ return data
+
+ @app.post("/simple-model-filter", response_model=SubItem)
+ def handle_simple_model_filter(data: SubItem) -> Any:
+ extended_data = data.dict()
+ extended_data.update({"secret_price": 42})
+ return extended_data
+
+ @app.post("/item")
+ def handle_item(data: Item) -> Item:
+ return data
+
+ @app.post("/item-filter", response_model=Item)
+ def handle_item_filter(data: Item) -> Any:
+ extended_data = data.dict()
+ extended_data.update({"secret_data": "classified", "internal_id": 12345})
+ extended_data["sub"].update({"internal_id": 67890})
+ return extended_data
client = TestClient(app)
import sys
+import warnings
from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314
app = FastAPI()
-@app.post("/item")
-def handle_item(data: Item) -> list[Item]:
- return [data, data]
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ @app.post("/item")
+ def handle_item(data: Item) -> list[Item]:
+ return [data, data]
-@app.post("/item-filter", response_model=list[Item])
-def handle_item_filter(data: Item) -> Any:
- extended_data = data.dict()
- extended_data.update({"secret_data": "classified", "internal_id": 12345})
- extended_data["sub"].update({"internal_id": 67890})
- return [extended_data, extended_data]
-
-
-@app.post("/item-list")
-def handle_item_list(data: list[Item]) -> Item:
- if data:
- return data[0]
- return Item(title="", size=0, sub=SubItem(name=""))
-
-
-@app.post("/item-list-filter", response_model=Item)
-def handle_item_list_filter(data: list[Item]) -> Any:
- if data:
- extended_data = data[0].dict()
- extended_data.update({"secret_data": "classified", "internal_id": 12345})
- extended_data["sub"].update({"internal_id": 67890})
- return extended_data
- return Item(title="", size=0, sub=SubItem(name=""))
-
-
-@app.post("/item-list-to-list")
-def handle_item_list_to_list(data: list[Item]) -> list[Item]:
- return data
-
-
-@app.post("/item-list-to-list-filter", response_model=list[Item])
-def handle_item_list_to_list_filter(data: list[Item]) -> Any:
- if data:
- extended_data = data[0].dict()
+ @app.post("/item-filter", response_model=list[Item])
+ def handle_item_filter(data: Item) -> Any:
+ extended_data = data.dict()
extended_data.update({"secret_data": "classified", "internal_id": 12345})
extended_data["sub"].update({"internal_id": 67890})
return [extended_data, extended_data]
- return []
+
+ @app.post("/item-list")
+ def handle_item_list(data: list[Item]) -> Item:
+ if data:
+ return data[0]
+ return Item(title="", size=0, sub=SubItem(name=""))
+
+ @app.post("/item-list-filter", response_model=Item)
+ def handle_item_list_filter(data: list[Item]) -> Any:
+ if data:
+ extended_data = data[0].dict()
+ extended_data.update({"secret_data": "classified", "internal_id": 12345})
+ extended_data["sub"].update({"internal_id": 67890})
+ return extended_data
+ return Item(title="", size=0, sub=SubItem(name=""))
+
+ @app.post("/item-list-to-list")
+ def handle_item_list_to_list(data: list[Item]) -> list[Item]:
+ return data
+
+ @app.post("/item-list-to-list-filter", response_model=list[Item])
+ def handle_item_list_to_list_filter(data: list[Item]) -> Any:
+ if data:
+ extended_data = data[0].dict()
+ extended_data.update({"secret_data": "classified", "internal_id": 12345})
+ extended_data["sub"].update({"internal_id": 67890})
+ return [extended_data, extended_data]
+ return []
client = TestClient(app)
import sys
+import warnings
from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314
app = FastAPI()
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
-@app.post("/v1-to-v2/item")
-def handle_v1_item_to_v2(data: Item) -> NewItem:
- return NewItem(
- new_title=data.title,
- new_size=data.size,
- new_description=data.description,
- new_sub=NewSubItem(new_sub_name=data.sub.name),
- new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
- )
-
-
-@app.post("/v1-to-v2/item-filter", response_model=NewItem)
-def handle_v1_item_to_v2_filter(data: Item) -> Any:
- result = {
- "new_title": data.title,
- "new_size": data.size,
- "new_description": data.description,
- "new_sub": {"new_sub_name": data.sub.name, "new_sub_secret": "sub_hidden"},
- "new_multi": [
- {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"} for s in data.multi
- ],
- "secret": "hidden_v1_to_v2",
- }
- return result
-
-
-@app.post("/v2-to-v1/item")
-def handle_v2_item_to_v1(data: NewItem) -> Item:
- return Item(
- title=data.new_title,
- size=data.new_size,
- description=data.new_description,
- sub=SubItem(name=data.new_sub.new_sub_name),
- multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
- )
-
-
-@app.post("/v2-to-v1/item-filter", response_model=Item)
-def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
- result = {
- "title": data.new_title,
- "size": data.new_size,
- "description": data.new_description,
- "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
- "multi": [
- {"name": s.new_sub_name, "sub_secret": "sub_hidden"} for s in data.new_multi
- ],
- "secret": "hidden_v2_to_v1",
- }
- return result
-
+ @app.post("/v1-to-v2/item")
+ def handle_v1_item_to_v2(data: Item) -> NewItem:
+ return NewItem(
+ new_title=data.title,
+ new_size=data.size,
+ new_description=data.description,
+ new_sub=NewSubItem(new_sub_name=data.sub.name),
+ new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
+ )
-@app.post("/v1-to-v2/item-to-list")
-def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]:
- converted = NewItem(
- new_title=data.title,
- new_size=data.size,
- new_description=data.description,
- new_sub=NewSubItem(new_sub_name=data.sub.name),
- new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
- )
- return [converted, converted]
+ @app.post("/v1-to-v2/item-filter", response_model=NewItem)
+ def handle_v1_item_to_v2_filter(data: Item) -> Any:
+ result = {
+ "new_title": data.title,
+ "new_size": data.size,
+ "new_description": data.description,
+ "new_sub": {
+ "new_sub_name": data.sub.name,
+ "new_sub_secret": "sub_hidden",
+ },
+ "new_multi": [
+ {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
+ for s in data.multi
+ ],
+ "secret": "hidden_v1_to_v2",
+ }
+ return result
+ @app.post("/v2-to-v1/item")
+ def handle_v2_item_to_v1(data: NewItem) -> Item:
+ return Item(
+ title=data.new_title,
+ size=data.new_size,
+ description=data.new_description,
+ sub=SubItem(name=data.new_sub.new_sub_name),
+ multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
+ )
-@app.post("/v1-to-v2/list-to-list")
-def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]:
- result = []
- for item in data:
- result.append(
- NewItem(
+ @app.post("/v2-to-v1/item-filter", response_model=Item)
+ def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
+ result = {
+ "title": data.new_title,
+ "size": data.new_size,
+ "description": data.new_description,
+ "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
+ "multi": [
+ {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
+ for s in data.new_multi
+ ],
+ "secret": "hidden_v2_to_v1",
+ }
+ return result
+
+ @app.post("/v1-to-v2/item-to-list")
+ def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]:
+ converted = NewItem(
+ new_title=data.title,
+ new_size=data.size,
+ new_description=data.description,
+ new_sub=NewSubItem(new_sub_name=data.sub.name),
+ new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
+ )
+ return [converted, converted]
+
+ @app.post("/v1-to-v2/list-to-list")
+ def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]:
+ result = []
+ for item in data:
+ result.append(
+ NewItem(
+ new_title=item.title,
+ new_size=item.size,
+ new_description=item.description,
+ new_sub=NewSubItem(new_sub_name=item.sub.name),
+ new_multi=[NewSubItem(new_sub_name=s.name) for s in item.multi],
+ )
+ )
+ return result
+
+ @app.post("/v1-to-v2/list-to-list-filter", response_model=list[NewItem])
+ def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
+ result = []
+ for item in data:
+ converted = {
+ "new_title": item.title,
+ "new_size": item.size,
+ "new_description": item.description,
+ "new_sub": {
+ "new_sub_name": item.sub.name,
+ "new_sub_secret": "sub_hidden",
+ },
+ "new_multi": [
+ {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
+ for s in item.multi
+ ],
+ "secret": "hidden_v2_to_v1",
+ }
+ result.append(converted)
+ return result
+
+ @app.post("/v1-to-v2/list-to-item")
+ def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem:
+ if data:
+ item = data[0]
+ return NewItem(
new_title=item.title,
new_size=item.size,
new_description=item.description,
new_sub=NewSubItem(new_sub_name=item.sub.name),
new_multi=[NewSubItem(new_sub_name=s.name) for s in item.multi],
)
+ return NewItem(new_title="", new_size=0, new_sub=NewSubItem(new_sub_name=""))
+
+ @app.post("/v2-to-v1/item-to-list")
+ def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]:
+ converted = Item(
+ title=data.new_title,
+ size=data.new_size,
+ description=data.new_description,
+ sub=SubItem(name=data.new_sub.new_sub_name),
+ multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
)
- return result
-
-
-@app.post("/v1-to-v2/list-to-list-filter", response_model=list[NewItem])
-def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
- result = []
- for item in data:
- converted = {
- "new_title": item.title,
- "new_size": item.size,
- "new_description": item.description,
- "new_sub": {"new_sub_name": item.sub.name, "new_sub_secret": "sub_hidden"},
- "new_multi": [
- {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
- for s in item.multi
- ],
- "secret": "hidden_v2_to_v1",
- }
- result.append(converted)
- return result
-
-
-@app.post("/v1-to-v2/list-to-item")
-def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem:
- if data:
- item = data[0]
- return NewItem(
- new_title=item.title,
- new_size=item.size,
- new_description=item.description,
- new_sub=NewSubItem(new_sub_name=item.sub.name),
- new_multi=[NewSubItem(new_sub_name=s.name) for s in item.multi],
- )
- return NewItem(new_title="", new_size=0, new_sub=NewSubItem(new_sub_name=""))
-
-
-@app.post("/v2-to-v1/item-to-list")
-def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]:
- converted = Item(
- title=data.new_title,
- size=data.new_size,
- description=data.new_description,
- sub=SubItem(name=data.new_sub.new_sub_name),
- multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
- )
- return [converted, converted]
-
-
-@app.post("/v2-to-v1/list-to-list")
-def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]:
- result = []
- for item in data:
- result.append(
- Item(
+ return [converted, converted]
+
+ @app.post("/v2-to-v1/list-to-list")
+ def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]:
+ result = []
+ for item in data:
+ result.append(
+ Item(
+ title=item.new_title,
+ size=item.new_size,
+ description=item.new_description,
+ sub=SubItem(name=item.new_sub.new_sub_name),
+ multi=[SubItem(name=s.new_sub_name) for s in item.new_multi],
+ )
+ )
+ return result
+
+ @app.post("/v2-to-v1/list-to-list-filter", response_model=list[Item])
+ def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
+ result = []
+ for item in data:
+ converted = {
+ "title": item.new_title,
+ "size": item.new_size,
+ "description": item.new_description,
+ "sub": {
+ "name": item.new_sub.new_sub_name,
+ "sub_secret": "sub_hidden",
+ },
+ "multi": [
+ {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
+ for s in item.new_multi
+ ],
+ "secret": "hidden_v2_to_v1",
+ }
+ result.append(converted)
+ return result
+
+ @app.post("/v2-to-v1/list-to-item")
+ def handle_v2_list_to_v1_item(data: list[NewItem]) -> Item:
+ if data:
+ item = data[0]
+ return Item(
title=item.new_title,
size=item.new_size,
description=item.new_description,
sub=SubItem(name=item.new_sub.new_sub_name),
multi=[SubItem(name=s.new_sub_name) for s in item.new_multi],
)
- )
- return result
-
-
-@app.post("/v2-to-v1/list-to-list-filter", response_model=list[Item])
-def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
- result = []
- for item in data:
- converted = {
- "title": item.new_title,
- "size": item.new_size,
- "description": item.new_description,
- "sub": {"name": item.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
- "multi": [
- {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
- for s in item.new_multi
- ],
- "secret": "hidden_v2_to_v1",
- }
- result.append(converted)
- return result
-
-
-@app.post("/v2-to-v1/list-to-item")
-def handle_v2_list_to_v1_item(data: list[NewItem]) -> Item:
- if data:
- item = data[0]
- return Item(
- title=item.new_title,
- size=item.new_size,
- description=item.new_description,
- sub=SubItem(name=item.new_sub.new_sub_name),
- multi=[SubItem(name=s.new_sub_name) for s in item.new_multi],
- )
- return Item(title="", size=0, sub=SubItem(name=""))
+ return Item(title="", size=0, sub=SubItem(name=""))
client = TestClient(app)
+import warnings
+
from fastapi import FastAPI
from . import modelsv1, modelsv2, modelsv2b
app = FastAPI()
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
-@app.post("/v1-to-v2/item")
-def handle_v1_item_to_v2(data: modelsv1.Item) -> modelsv2.Item:
- return modelsv2.Item(
- new_title=data.title,
- new_size=data.size,
- new_description=data.description,
- new_sub=modelsv2.SubItem(new_sub_name=data.sub.name),
- new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi],
- )
-
-
-@app.post("/v2-to-v1/item")
-def handle_v2_item_to_v1(data: modelsv2.Item) -> modelsv1.Item:
- return modelsv1.Item(
- title=data.new_title,
- size=data.new_size,
- description=data.new_description,
- sub=modelsv1.SubItem(name=data.new_sub.new_sub_name),
- multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi],
- )
-
+ @app.post("/v1-to-v2/item")
+ def handle_v1_item_to_v2(data: modelsv1.Item) -> modelsv2.Item:
+ return modelsv2.Item(
+ new_title=data.title,
+ new_size=data.size,
+ new_description=data.description,
+ new_sub=modelsv2.SubItem(new_sub_name=data.sub.name),
+ new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi],
+ )
-@app.post("/v1-to-v2/item-to-list")
-def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]:
- converted = modelsv2.Item(
- new_title=data.title,
- new_size=data.size,
- new_description=data.description,
- new_sub=modelsv2.SubItem(new_sub_name=data.sub.name),
- new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi],
- )
- return [converted, converted]
+ @app.post("/v2-to-v1/item")
+ def handle_v2_item_to_v1(data: modelsv2.Item) -> modelsv1.Item:
+ return modelsv1.Item(
+ title=data.new_title,
+ size=data.new_size,
+ description=data.new_description,
+ sub=modelsv1.SubItem(name=data.new_sub.new_sub_name),
+ multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi],
+ )
+ @app.post("/v1-to-v2/item-to-list")
+ def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]:
+ converted = modelsv2.Item(
+ new_title=data.title,
+ new_size=data.size,
+ new_description=data.description,
+ new_sub=modelsv2.SubItem(new_sub_name=data.sub.name),
+ new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi],
+ )
+ return [converted, converted]
+
+ @app.post("/v1-to-v2/list-to-list")
+ def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]:
+ result = []
+ for item in data:
+ result.append(
+ modelsv2.Item(
+ new_title=item.title,
+ new_size=item.size,
+ new_description=item.description,
+ new_sub=modelsv2.SubItem(new_sub_name=item.sub.name),
+ new_multi=[
+ modelsv2.SubItem(new_sub_name=s.name) for s in item.multi
+ ],
+ )
+ )
+ return result
-@app.post("/v1-to-v2/list-to-list")
-def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]:
- result = []
- for item in data:
- result.append(
- modelsv2.Item(
+ @app.post("/v1-to-v2/list-to-item")
+ def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item:
+ if data:
+ item = data[0]
+ return modelsv2.Item(
new_title=item.title,
new_size=item.size,
new_description=item.description,
new_sub=modelsv2.SubItem(new_sub_name=item.sub.name),
new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in item.multi],
)
- )
- return result
-
-
-@app.post("/v1-to-v2/list-to-item")
-def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item:
- if data:
- item = data[0]
return modelsv2.Item(
- new_title=item.title,
- new_size=item.size,
- new_description=item.description,
- new_sub=modelsv2.SubItem(new_sub_name=item.sub.name),
- new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in item.multi],
+ new_title="", new_size=0, new_sub=modelsv2.SubItem(new_sub_name="")
)
- return modelsv2.Item(
- new_title="", new_size=0, new_sub=modelsv2.SubItem(new_sub_name="")
- )
-
-
-@app.post("/v2-to-v1/item-to-list")
-def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]:
- converted = modelsv1.Item(
- title=data.new_title,
- size=data.new_size,
- description=data.new_description,
- sub=modelsv1.SubItem(name=data.new_sub.new_sub_name),
- multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi],
- )
- return [converted, converted]
+ @app.post("/v2-to-v1/item-to-list")
+ def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]:
+ converted = modelsv1.Item(
+ title=data.new_title,
+ size=data.new_size,
+ description=data.new_description,
+ sub=modelsv1.SubItem(name=data.new_sub.new_sub_name),
+ multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi],
+ )
+ return [converted, converted]
+
+ @app.post("/v2-to-v1/list-to-list")
+ def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]:
+ result = []
+ for item in data:
+ result.append(
+ modelsv1.Item(
+ title=item.new_title,
+ size=item.new_size,
+ description=item.new_description,
+ sub=modelsv1.SubItem(name=item.new_sub.new_sub_name),
+ multi=[
+ modelsv1.SubItem(name=s.new_sub_name) for s in item.new_multi
+ ],
+ )
+ )
+ return result
-@app.post("/v2-to-v1/list-to-list")
-def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]:
- result = []
- for item in data:
- result.append(
- modelsv1.Item(
+ @app.post("/v2-to-v1/list-to-item")
+ def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item:
+ if data:
+ item = data[0]
+ return modelsv1.Item(
title=item.new_title,
size=item.new_size,
description=item.new_description,
sub=modelsv1.SubItem(name=item.new_sub.new_sub_name),
multi=[modelsv1.SubItem(name=s.new_sub_name) for s in item.new_multi],
)
- )
- return result
-
+ return modelsv1.Item(title="", size=0, sub=modelsv1.SubItem(name=""))
-@app.post("/v2-to-v1/list-to-item")
-def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item:
- if data:
- item = data[0]
+ @app.post("/v2-to-v1/same-name")
+ def handle_v2_same_name_to_v1(
+ item1: modelsv2.Item, item2: modelsv2b.Item
+ ) -> modelsv1.Item:
return modelsv1.Item(
- title=item.new_title,
- size=item.new_size,
- description=item.new_description,
- sub=modelsv1.SubItem(name=item.new_sub.new_sub_name),
- multi=[modelsv1.SubItem(name=s.new_sub_name) for s in item.new_multi],
+ title=item1.new_title,
+ size=item2.dup_size,
+ description=item1.new_description,
+ sub=modelsv1.SubItem(name=item1.new_sub.new_sub_name),
+ multi=[modelsv1.SubItem(name=s.dup_sub_name) for s in item2.dup_multi],
)
- return modelsv1.Item(title="", size=0, sub=modelsv1.SubItem(name=""))
-
-
-@app.post("/v2-to-v1/same-name")
-def handle_v2_same_name_to_v1(
- item1: modelsv2.Item, item2: modelsv2b.Item
-) -> modelsv1.Item:
- return modelsv1.Item(
- title=item1.new_title,
- size=item2.dup_size,
- description=item1.new_description,
- sub=modelsv1.SubItem(name=item1.new_sub.new_sub_name),
- multi=[modelsv1.SubItem(name=s.dup_sub_name) for s in item2.dup_multi],
- )
-
-@app.post("/v2-to-v1/list-of-items-to-list-of-items")
-def handle_v2_items_in_list_to_v1_item_in_list(
- data1: list[modelsv2.ItemInList], data2: list[modelsv2b.ItemInList]
-) -> list[modelsv1.ItemInList]:
- result = []
- item1 = data1[0]
- item2 = data2[0]
- result = [
- modelsv1.ItemInList(name1=item1.name2),
- modelsv1.ItemInList(name1=item2.dup_name2),
- ]
- return result
+ @app.post("/v2-to-v1/list-of-items-to-list-of-items")
+ def handle_v2_items_in_list_to_v1_item_in_list(
+ data1: list[modelsv2.ItemInList], data2: list[modelsv2b.ItemInList]
+ ) -> list[modelsv1.ItemInList]:
+ item1 = data1[0]
+ item2 = data2[0]
+ return [
+ modelsv1.ItemInList(name1=item1.name2),
+ modelsv1.ItemInList(name1=item2.dup_name2),
+ ]
import sys
+import warnings
from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314
app = FastAPI()
-
-@app.post("/v1-to-v2/")
-def handle_v1_item_to_v2(data: Item) -> Union[NewItem, None]:
- if data.size < 0:
- return None
- return NewItem(
- new_title=data.title,
- new_size=data.size,
- new_description=data.description,
- new_sub=NewSubItem(new_sub_name=data.sub.name),
- new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
- )
-
-
-@app.post("/v1-to-v2/item-filter", response_model=Union[NewItem, None])
-def handle_v1_item_to_v2_filter(data: Item) -> Any:
- if data.size < 0:
- return None
- result = {
- "new_title": data.title,
- "new_size": data.size,
- "new_description": data.description,
- "new_sub": {"new_sub_name": data.sub.name, "new_sub_secret": "sub_hidden"},
- "new_multi": [
- {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"} for s in data.multi
- ],
- "secret": "hidden_v1_to_v2",
- }
- return result
-
-
-@app.post("/v2-to-v1/item")
-def handle_v2_item_to_v1(data: NewItem) -> Union[Item, None]:
- if data.new_size < 0:
- return None
- return Item(
- title=data.new_title,
- size=data.new_size,
- description=data.new_description,
- sub=SubItem(name=data.new_sub.new_sub_name),
- multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
- )
-
-
-@app.post("/v2-to-v1/item-filter", response_model=Union[Item, None])
-def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
- if data.new_size < 0:
- return None
- result = {
- "title": data.new_title,
- "size": data.new_size,
- "description": data.new_description,
- "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
- "multi": [
- {"name": s.new_sub_name, "sub_secret": "sub_hidden"} for s in data.new_multi
- ],
- "secret": "hidden_v2_to_v1",
- }
- return result
+with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.post("/v1-to-v2/")
+ def handle_v1_item_to_v2(data: Item) -> Union[NewItem, None]:
+ if data.size < 0:
+ return None
+ return NewItem(
+ new_title=data.title,
+ new_size=data.size,
+ new_description=data.description,
+ new_sub=NewSubItem(new_sub_name=data.sub.name),
+ new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
+ )
+
+ @app.post("/v1-to-v2/item-filter", response_model=Union[NewItem, None])
+ def handle_v1_item_to_v2_filter(data: Item) -> Any:
+ if data.size < 0:
+ return None
+ result = {
+ "new_title": data.title,
+ "new_size": data.size,
+ "new_description": data.description,
+ "new_sub": {
+ "new_sub_name": data.sub.name,
+ "new_sub_secret": "sub_hidden",
+ },
+ "new_multi": [
+ {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
+ for s in data.multi
+ ],
+ "secret": "hidden_v1_to_v2",
+ }
+ return result
+
+ @app.post("/v2-to-v1/item")
+ def handle_v2_item_to_v1(data: NewItem) -> Union[Item, None]:
+ if data.new_size < 0:
+ return None
+ return Item(
+ title=data.new_title,
+ size=data.new_size,
+ description=data.new_description,
+ sub=SubItem(name=data.new_sub.new_sub_name),
+ multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
+ )
+
+ @app.post("/v2-to-v1/item-filter", response_model=Union[Item, None])
+ def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
+ if data.new_size < 0:
+ return None
+ result = {
+ "title": data.new_title,
+ "size": data.new_size,
+ "description": data.new_description,
+ "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
+ "multi": [
+ {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
+ for s in data.new_multi
+ ],
+ "secret": "hidden_v2_to_v1",
+ }
+ return result
client = TestClient(app)
+import warnings
from typing import Any
from fastapi import FastAPI
app = FastAPI()
- @app.post("/people/", response_model=PersonRead)
- def create_person(person: PersonCreate) -> Any:
- db_person = Person.from_orm(person)
- return db_person
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+
+ @app.post("/people/", response_model=PersonRead)
+ def create_person(person: PersonCreate) -> Any:
+ db_person = Person.from_orm(person)
+ return db_person
client = TestClient(app)
+import warnings
from typing import Union
import pytest
class Model(v1.BaseModel):
foo: str
- with pytest.raises(FastAPIError) as e:
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
- @app.get("/")
- def read_root() -> Union[Response, Model, None]:
- return Response(content="Foo") # pragma: no cover
+ with pytest.raises(FastAPIError) as e:
+
+ @app.get("/")
+ def read_root() -> Union[Response, Model, None]:
+ return Response(content="Foo") # pragma: no cover
assert "valid Pydantic field type" in e.value.args[0]
assert "parameter response_model=None" in e.value.args[0]
import sys
+import warnings
import pytest
from inline_snapshot import snapshot
],
)
def get_client(request: pytest.FixtureRequest):
- mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+ mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
c = TestClient(mod.app)
return c
import sys
+import warnings
import pytest
from inline_snapshot import snapshot
],
)
def get_client(request: pytest.FixtureRequest):
- mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+ mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
c = TestClient(mod.app)
return c
import sys
+import warnings
import pytest
from inline_snapshot import snapshot
],
)
def get_client(request: pytest.FixtureRequest):
- mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+ mod = importlib.import_module(f"docs_src.pydantic_v1_in_v2.{request.param}")
c = TestClient(mod.app)
return c
import importlib
+import warnings
import pytest
from fastapi.testclient import TestClient
],
)
def get_client(request: pytest.FixtureRequest):
- mod = importlib.import_module(f"docs_src.request_form_models.{request.param}")
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+ mod = importlib.import_module(f"docs_src.request_form_models.{request.param}")
client = TestClient(mod.app)
return client
import importlib
+import warnings
import pytest
from fastapi.testclient import TestClient
],
)
def get_client(request: pytest.FixtureRequest):
- mod = importlib.import_module(f"docs_src.schema_extra_example.{request.param}")
+ with warnings.catch_warnings(record=True):
+ warnings.filterwarnings(
+ "ignore",
+ message=r"pydantic\.v1 is deprecated and will soon stop being supported by FastAPI\..*",
+ category=DeprecationWarning,
+ )
+ mod = importlib.import_module(f"docs_src.schema_extra_example.{request.param}")
client = TestClient(mod.app)
return client