Browse Source

Refactor tests, modernize syntax, do not use ellipsis (`...`), and use `Annotated`

pull/14358/head
Sebastián Ramírez 7 months ago
parent
commit
da5cc98880
  1. 19
      tests/test_request_params/test_body/test_list.py
  2. 18
      tests/test_request_params/test_body/test_optional_list.py
  3. 15
      tests/test_request_params/test_body/test_optional_str.py
  4. 19
      tests/test_request_params/test_body/test_required_str.py
  5. 13
      tests/test_request_params/test_cookie/test_optional_str.py
  6. 15
      tests/test_request_params/test_cookie/test_required_str.py
  7. 37
      tests/test_request_params/test_file/test_list.py
  8. 43
      tests/test_request_params/test_file/test_optional.py
  9. 46
      tests/test_request_params/test_file/test_optional_list.py
  10. 35
      tests/test_request_params/test_file/test_required.py
  11. 15
      tests/test_request_params/test_form/test_list.py
  12. 15
      tests/test_request_params/test_form/test_optional_list.py
  13. 13
      tests/test_request_params/test_form/test_optional_str.py
  14. 15
      tests/test_request_params/test_form/test_required_str.py
  15. 15
      tests/test_request_params/test_header/test_list.py
  16. 15
      tests/test_request_params/test_header/test_optional_list.py
  17. 13
      tests/test_request_params/test_header/test_optional_str.py
  18. 15
      tests/test_request_params/test_header/test_required_str.py
  19. 9
      tests/test_request_params/test_path/test_required_str.py
  20. 15
      tests/test_request_params/test_query/test_list.py
  21. 15
      tests/test_request_params/test_query/test_optional_list.py
  22. 11
      tests/test_request_params/test_query/test_optional_str.py
  23. 13
      tests/test_request_params/test_query/test_required_str.py

19
tests/test_request_params/test_body/test_list.py

@ -6,6 +6,7 @@ from fastapi import Body, FastAPI
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,7 @@ app = FastAPI()
@app.post("/required-list-str", operation_id="required_list_str") @app.post("/required-list-str", operation_id="required_list_str")
async def read_required_list_str(p: List[str] = Body(..., embed=True)): async def read_required_list_str(p: Annotated[List[str], Body(embed=True)]):
return {"p": p} return {"p": p}
@ -103,13 +104,13 @@ def test_required_list_str(path: str):
@app.post("/required-list-alias", operation_id="required_list_alias") @app.post("/required-list-alias", operation_id="required_list_alias")
async def read_required_list_alias( async def read_required_list_alias(
p: List[str] = Body(..., embed=True, alias="p_alias"), p: Annotated[List[str], Body(embed=True, alias="p_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredListAlias(BaseModel): class FormModelRequiredListAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias") p: List[str] = Field(alias="p_alias")
@app.post("/model-required-list-alias", operation_id="model_required_list_alias") @app.post("/model-required-list-alias", operation_id="model_required_list_alias")
@ -236,13 +237,13 @@ def test_required_list_alias_by_alias(path: str):
"/required-list-validation-alias", operation_id="required_list_validation_alias" "/required-list-validation-alias", operation_id="required_list_validation_alias"
) )
def read_required_list_validation_alias( def read_required_list_validation_alias(
p: List[str] = Body(..., embed=True, validation_alias="p_val_alias"), p: Annotated[List[str], Body(embed=True, validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredListValidationAlias(BaseModel): class FormModelRequiredListValidationAlias(BaseModel):
p: List[str] = Field(..., validation_alias="p_val_alias") p: List[str] = Field(validation_alias="p_val_alias")
@app.post( @app.post(
@ -367,15 +368,15 @@ def test_required_list_validation_alias_by_validation_alias(path: str):
operation_id="required_list_alias_and_validation_alias", operation_id="required_list_alias_and_validation_alias",
) )
def read_required_list_alias_and_validation_alias( def read_required_list_alias_and_validation_alias(
p: List[str] = Body( p: Annotated[
..., embed=True, alias="p_alias", validation_alias="p_val_alias" List[str], Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
), ],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredListAliasAndValidationAlias(BaseModel): class FormModelRequiredListAliasAndValidationAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias", validation_alias="p_val_alias") p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

18
tests/test_request_params/test_body/test_optional_list.py

@ -6,6 +6,7 @@ from fastapi import Body, FastAPI
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,9 @@ app = FastAPI()
@app.post("/optional-list-str", operation_id="optional_list_str") @app.post("/optional-list-str", operation_id="optional_list_str")
async def read_optional_list_str(p: Optional[List[str]] = Body(None, embed=True)): async def read_optional_list_str(
p: Annotated[Optional[List[str]], Body(embed=True)] = None,
):
return {"p": p} return {"p": p}
@ -129,7 +132,7 @@ def test_optional_list_str(path: str):
@app.post("/optional-list-alias", operation_id="optional_list_alias") @app.post("/optional-list-alias", operation_id="optional_list_alias")
async def read_optional_list_alias( async def read_optional_list_alias(
p: Optional[List[str]] = Body(None, embed=True, alias="p_alias"), p: Annotated[Optional[List[str]], Body(embed=True, alias="p_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -269,7 +272,9 @@ def test_optional_list_alias_by_alias(path: str):
"/optional-list-validation-alias", operation_id="optional_list_validation_alias" "/optional-list-validation-alias", operation_id="optional_list_validation_alias"
) )
def read_optional_list_validation_alias( def read_optional_list_validation_alias(
p: Optional[List[str]] = Body(None, embed=True, validation_alias="p_val_alias"), p: Annotated[
Optional[List[str]], Body(embed=True, validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}
@ -421,9 +426,10 @@ def test_optional_list_validation_alias_by_validation_alias(path: str):
operation_id="optional_list_alias_and_validation_alias", operation_id="optional_list_alias_and_validation_alias",
) )
def read_optional_list_alias_and_validation_alias( def read_optional_list_alias_and_validation_alias(
p: Optional[List[str]] = Body( p: Annotated[
None, embed=True, alias="p_alias", validation_alias="p_val_alias" Optional[List[str]],
), Body(embed=True, alias="p_alias", validation_alias="p_val_alias"),
] = None,
): ):
return {"p": p} return {"p": p}

15
tests/test_request_params/test_body/test_optional_str.py

@ -6,6 +6,7 @@ from fastapi import Body, FastAPI
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,7 @@ app = FastAPI()
@app.post("/optional-str", operation_id="optional_str") @app.post("/optional-str", operation_id="optional_str")
async def read_optional_str(p: Optional[str] = Body(None, embed=True)): async def read_optional_str(p: Annotated[Optional[str], Body(embed=True)] = None):
return {"p": p} return {"p": p}
@ -126,7 +127,7 @@ def test_optional_str(path: str):
@app.post("/optional-alias", operation_id="optional_alias") @app.post("/optional-alias", operation_id="optional_alias")
async def read_optional_alias( async def read_optional_alias(
p: Optional[str] = Body(None, embed=True, alias="p_alias"), p: Annotated[Optional[str], Body(embed=True, alias="p_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -257,7 +258,9 @@ def test_optional_alias_by_alias(path: str):
@app.post("/optional-validation-alias", operation_id="optional_validation_alias") @app.post("/optional-validation-alias", operation_id="optional_validation_alias")
def read_optional_validation_alias( def read_optional_validation_alias(
p: Optional[str] = Body(None, embed=True, validation_alias="p_val_alias"), p: Annotated[
Optional[str], Body(embed=True, validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}
@ -402,9 +405,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
operation_id="optional_alias_and_validation_alias", operation_id="optional_alias_and_validation_alias",
) )
def read_optional_alias_and_validation_alias( def read_optional_alias_and_validation_alias(
p: Optional[str] = Body( p: Annotated[
None, embed=True, alias="p_alias", validation_alias="p_val_alias" Optional[str], Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"p": p} return {"p": p}

19
tests/test_request_params/test_body/test_required_str.py

@ -6,6 +6,7 @@ from fastapi import Body, FastAPI
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,7 @@ app = FastAPI()
@app.post("/required-str", operation_id="required_str") @app.post("/required-str", operation_id="required_str")
async def read_required_str(p: str = Body(..., embed=True)): async def read_required_str(p: Annotated[str, Body(embed=True)]):
return {"p": p} return {"p": p}
@ -99,12 +100,14 @@ def test_required_str(path: str):
@app.post("/required-alias", operation_id="required_alias") @app.post("/required-alias", operation_id="required_alias")
async def read_required_alias(p: str = Body(..., embed=True, alias="p_alias")): async def read_required_alias(
p: Annotated[str, Body(embed=True, alias="p_alias")],
):
return {"p": p} return {"p": p}
class FormModelRequiredAlias(BaseModel): class FormModelRequiredAlias(BaseModel):
p: str = Field(..., alias="p_alias") p: str = Field(alias="p_alias")
@app.post("/model-required-alias", operation_id="model_required_alias") @app.post("/model-required-alias", operation_id="model_required_alias")
@ -225,13 +228,13 @@ def test_required_alias_by_alias(path: str):
@app.post("/required-validation-alias", operation_id="required_validation_alias") @app.post("/required-validation-alias", operation_id="required_validation_alias")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Body(..., embed=True, validation_alias="p_val_alias"), p: Annotated[str, Body(embed=True, validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredValidationAlias(BaseModel): class FormModelRequiredValidationAlias(BaseModel):
p: str = Field(..., validation_alias="p_val_alias") p: str = Field(validation_alias="p_val_alias")
@app.post( @app.post(
@ -354,13 +357,15 @@ def test_required_validation_alias_by_validation_alias(path: str):
operation_id="required_alias_and_validation_alias", operation_id="required_alias_and_validation_alias",
) )
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Body(..., embed=True, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
str, Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredAliasAndValidationAlias(BaseModel): class FormModelRequiredAliasAndValidationAlias(BaseModel):
p: str = Field(..., alias="p_alias", validation_alias="p_val_alias") p: str = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

13
tests/test_request_params/test_cookie/test_optional_str.py

@ -5,6 +5,7 @@ from dirty_equals import IsDict
from fastapi import Cookie, FastAPI from fastapi import Cookie, FastAPI
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -15,7 +16,7 @@ app = FastAPI()
@app.get("/optional-str") @app.get("/optional-str")
async def read_optional_str(p: Optional[str] = Cookie(None)): async def read_optional_str(p: Annotated[Optional[str], Cookie()] = None):
return {"p": p} return {"p": p}
@ -85,7 +86,9 @@ def test_optional_str(path: str):
@app.get("/optional-alias") @app.get("/optional-alias")
async def read_optional_alias(p: Optional[str] = Cookie(None, alias="p_alias")): async def read_optional_alias(
p: Annotated[Optional[str], Cookie(alias="p_alias")] = None,
):
return {"p": p} return {"p": p}
@ -174,7 +177,7 @@ def test_optional_alias_by_alias(path: str):
@app.get("/optional-validation-alias") @app.get("/optional-validation-alias")
def read_optional_validation_alias( def read_optional_validation_alias(
p: Optional[str] = Cookie(None, validation_alias="p_val_alias"), p: Annotated[Optional[str], Cookie(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -266,7 +269,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
@app.get("/optional-alias-and-validation-alias") @app.get("/optional-alias-and-validation-alias")
def read_optional_alias_and_validation_alias( def read_optional_alias_and_validation_alias(
p: Optional[str] = Cookie(None, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
Optional[str], Cookie(alias="p_alias", validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}

15
tests/test_request_params/test_cookie/test_required_str.py

@ -4,6 +4,7 @@ from fastapi import Cookie, FastAPI
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -14,7 +15,7 @@ app = FastAPI()
@app.get("/required-str") @app.get("/required-str")
async def read_required_str(p: str = Cookie(...)): async def read_required_str(p: Annotated[str, Cookie()]):
return {"p": p} return {"p": p}
@ -92,12 +93,12 @@ def test_required_str(path: str):
@app.get("/required-alias") @app.get("/required-alias")
async def read_required_alias(p: str = Cookie(..., alias="p_alias")): async def read_required_alias(p: Annotated[str, Cookie(alias="p_alias")]):
return {"p": p} return {"p": p}
class CookieModelRequiredAlias(BaseModel): class CookieModelRequiredAlias(BaseModel):
p: str = Field(..., alias="p_alias") p: str = Field(alias="p_alias")
@app.get("/model-required-alias") @app.get("/model-required-alias")
@ -227,13 +228,13 @@ def test_required_alias_by_alias(path: str):
@app.get("/required-validation-alias") @app.get("/required-validation-alias")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Cookie(..., validation_alias="p_val_alias"), p: Annotated[str, Cookie(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class CookieModelRequiredValidationAlias(BaseModel): class CookieModelRequiredValidationAlias(BaseModel):
p: str = Field(..., validation_alias="p_val_alias") p: str = Field(validation_alias="p_val_alias")
@app.get("/model-required-validation-alias") @app.get("/model-required-validation-alias")
@ -349,13 +350,13 @@ def test_required_validation_alias_by_validation_alias(path: str):
@app.get("/required-alias-and-validation-alias") @app.get("/required-alias-and-validation-alias")
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Cookie(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[str, Cookie(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class CookieModelRequiredAliasAndValidationAlias(BaseModel): class CookieModelRequiredAliasAndValidationAlias(BaseModel):
p: str = Field(..., alias="p_alias", validation_alias="p_val_alias") p: str = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-alias-and-validation-alias") @app.get("/model-required-alias-and-validation-alias")

37
tests/test_request_params/test_file/test_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, File, Form, UploadFile
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,17 +19,17 @@ app = FastAPI()
@app.post("/list-bytes", operation_id="list_bytes") @app.post("/list-bytes", operation_id="list_bytes")
async def read_list_bytes(p: List[bytes] = File(...)): async def read_list_bytes(p: Annotated[List[bytes], File()]):
return {"file_size": [len(file) for file in p]} return {"file_size": [len(file) for file in p]}
@app.post("/list-uploadfile", operation_id="list_uploadfile") @app.post("/list-uploadfile", operation_id="list_uploadfile")
async def read_list_uploadfile(p: List[UploadFile] = File(...)): async def read_list_uploadfile(p: Annotated[List[UploadFile], File()]):
return {"file_size": [file.size for file in p]} return {"file_size": [file.size for file in p]}
class FormModelListBytes(BaseModel): class FormModelListBytes(BaseModel):
p: List[bytes] = File(...) p: List[bytes] = File()
@app.post("/model-list-bytes", operation_id="model_list_bytes") @app.post("/model-list-bytes", operation_id="model_list_bytes")
@ -41,7 +42,7 @@ async def read_model_list_bytes(
class FormModelListUploadFile(BaseModel): class FormModelListUploadFile(BaseModel):
p: List[UploadFile] = File(...) p: List[UploadFile] = File()
@app.post("/model-list-uploadfile", operation_id="model_list_uploadfile") @app.post("/model-list-uploadfile", operation_id="model_list_uploadfile")
@ -155,17 +156,19 @@ def test_list(path: str):
@app.post("/list-bytes-alias", operation_id="list_bytes_alias") @app.post("/list-bytes-alias", operation_id="list_bytes_alias")
async def read_list_bytes_alias(p: List[bytes] = File(..., alias="p_alias")): async def read_list_bytes_alias(p: Annotated[List[bytes], File(alias="p_alias")]):
return {"file_size": [len(file) for file in p]} return {"file_size": [len(file) for file in p]}
@app.post("/list-uploadfile-alias", operation_id="list_uploadfile_alias") @app.post("/list-uploadfile-alias", operation_id="list_uploadfile_alias")
async def read_list_uploadfile_alias(p: List[UploadFile] = File(..., alias="p_alias")): async def read_list_uploadfile_alias(
p: Annotated[List[UploadFile], File(alias="p_alias")],
):
return {"file_size": [file.size for file in p]} return {"file_size": [file.size for file in p]}
class FormModelListBytesAlias(BaseModel): class FormModelListBytesAlias(BaseModel):
p: List[bytes] = File(..., alias="p_alias") p: List[bytes] = File(alias="p_alias")
@app.post("/model-list-bytes-alias", operation_id="model_list_bytes_alias") @app.post("/model-list-bytes-alias", operation_id="model_list_bytes_alias")
@ -178,7 +181,7 @@ async def read_model_list_bytes_alias(
class FormModelListUploadFileAlias(BaseModel): class FormModelListUploadFileAlias(BaseModel):
p: List[UploadFile] = File(..., alias="p_alias") p: List[UploadFile] = File(alias="p_alias")
@app.post("/model-list-uploadfile-alias", operation_id="model_list_uploadfile_alias") @app.post("/model-list-uploadfile-alias", operation_id="model_list_uploadfile_alias")
@ -390,7 +393,7 @@ def test_list_alias_by_alias(path: str):
@app.post("/list-bytes-validation-alias", operation_id="list_bytes_validation_alias") @app.post("/list-bytes-validation-alias", operation_id="list_bytes_validation_alias")
def read_list_bytes_validation_alias( def read_list_bytes_validation_alias(
p: List[bytes] = File(..., validation_alias="p_val_alias"), p: Annotated[List[bytes], File(validation_alias="p_val_alias")],
): ):
return {"file_size": [len(file) for file in p]} return {"file_size": [len(file) for file in p]}
@ -400,13 +403,13 @@ def read_list_bytes_validation_alias(
operation_id="list_uploadfile_validation_alias", operation_id="list_uploadfile_validation_alias",
) )
def read_list_uploadfile_validation_alias( def read_list_uploadfile_validation_alias(
p: List[UploadFile] = File(..., validation_alias="p_val_alias"), p: Annotated[List[UploadFile], File(validation_alias="p_val_alias")],
): ):
return {"file_size": [file.size for file in p]} return {"file_size": [file.size for file in p]}
class FormModelRequiredBytesValidationAlias(BaseModel): class FormModelRequiredBytesValidationAlias(BaseModel):
p: List[bytes] = File(..., validation_alias="p_val_alias") p: List[bytes] = File(validation_alias="p_val_alias")
@app.post( @app.post(
@ -422,7 +425,7 @@ def read_model_list_bytes_validation_alias(
class FormModelRequiredUploadFileValidationAlias(BaseModel): class FormModelRequiredUploadFileValidationAlias(BaseModel):
p: List[UploadFile] = File(..., validation_alias="p_val_alias") p: List[UploadFile] = File(validation_alias="p_val_alias")
@app.post( @app.post(
@ -586,7 +589,7 @@ def test_list_validation_alias_by_validation_alias(path: str):
operation_id="list_bytes_alias_and_validation_alias", operation_id="list_bytes_alias_and_validation_alias",
) )
def read_list_bytes_alias_and_validation_alias( def read_list_bytes_alias_and_validation_alias(
p: List[bytes] = File(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[List[bytes], File(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"file_size": [len(file) for file in p]} return {"file_size": [len(file) for file in p]}
@ -596,13 +599,15 @@ def read_list_bytes_alias_and_validation_alias(
operation_id="list_uploadfile_alias_and_validation_alias", operation_id="list_uploadfile_alias_and_validation_alias",
) )
def read_list_uploadfile_alias_and_validation_alias( def read_list_uploadfile_alias_and_validation_alias(
p: List[UploadFile] = File(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
List[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
],
): ):
return {"file_size": [file.size for file in p]} return {"file_size": [file.size for file in p]}
class FormModelRequiredBytesAliasAndValidationAlias(BaseModel): class FormModelRequiredBytesAliasAndValidationAlias(BaseModel):
p: List[bytes] = File(..., alias="p_alias", validation_alias="p_val_alias") p: List[bytes] = File(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(
@ -618,7 +623,7 @@ def read_model_list_bytes_alias_and_validation_alias(
class FormModelRequiredUploadFileAliasAndValidationAlias(BaseModel): class FormModelRequiredUploadFileAliasAndValidationAlias(BaseModel):
p: List[UploadFile] = File(..., alias="p_alias", validation_alias="p_val_alias") p: List[UploadFile] = File(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

43
tests/test_request_params/test_file/test_optional.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, File, Form, UploadFile
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,17 +19,17 @@ app = FastAPI()
@app.post("/optional-bytes", operation_id="optional_bytes") @app.post("/optional-bytes", operation_id="optional_bytes")
async def read_optional_bytes(p: Optional[bytes] = File(None)): async def read_optional_bytes(p: Annotated[Optional[bytes], File()] = None):
return {"file_size": len(p) if p else None} return {"file_size": len(p) if p else None}
@app.post("/optional-uploadfile", operation_id="optional_uploadfile") @app.post("/optional-uploadfile", operation_id="optional_uploadfile")
async def read_optional_uploadfile(p: Optional[UploadFile] = File(None)): async def read_optional_uploadfile(p: Annotated[Optional[UploadFile], File()] = None):
return {"file_size": p.size if p else None} return {"file_size": p.size if p else None}
class FormModelOptionalBytes(BaseModel): class FormModelOptionalBytes(BaseModel):
p: Optional[bytes] = File(None) p: Optional[bytes] = File(default=None)
@app.post("/model-optional-bytes", operation_id="model_optional_bytes") @app.post("/model-optional-bytes", operation_id="model_optional_bytes")
@ -41,7 +42,7 @@ async def read_model_optional_bytes(
class FormModelOptionalUploadFile(BaseModel): class FormModelOptionalUploadFile(BaseModel):
p: Optional[UploadFile] = File(None) p: Optional[UploadFile] = File(default=None)
@app.post("/model-optional-uploadfile", operation_id="model_optional_uploadfile") @app.post("/model-optional-uploadfile", operation_id="model_optional_uploadfile")
@ -126,19 +127,21 @@ def test_optional(path: str):
@app.post("/optional-bytes-alias", operation_id="optional_bytes_alias") @app.post("/optional-bytes-alias", operation_id="optional_bytes_alias")
async def read_optional_bytes_alias(p: Optional[bytes] = File(None, alias="p_alias")): async def read_optional_bytes_alias(
p: Annotated[Optional[bytes], File(alias="p_alias")] = None,
):
return {"file_size": len(p) if p else None} return {"file_size": len(p) if p else None}
@app.post("/optional-uploadfile-alias", operation_id="optional_uploadfile_alias") @app.post("/optional-uploadfile-alias", operation_id="optional_uploadfile_alias")
async def read_optional_uploadfile_alias( async def read_optional_uploadfile_alias(
p: Optional[UploadFile] = File(None, alias="p_alias"), p: Annotated[Optional[UploadFile], File(alias="p_alias")] = None,
): ):
return {"file_size": p.size if p else None} return {"file_size": p.size if p else None}
class FormModelOptionalBytesAlias(BaseModel): class FormModelOptionalBytesAlias(BaseModel):
p: Optional[bytes] = File(None, alias="p_alias") p: Optional[bytes] = File(default=None, alias="p_alias")
@app.post("/model-optional-bytes-alias", operation_id="model_optional_bytes_alias") @app.post("/model-optional-bytes-alias", operation_id="model_optional_bytes_alias")
@ -151,7 +154,7 @@ async def read_model_optional_bytes_alias(
class FormModelOptionalUploadFileAlias(BaseModel): class FormModelOptionalUploadFileAlias(BaseModel):
p: Optional[UploadFile] = File(None, alias="p_alias") p: Optional[UploadFile] = File(default=None, alias="p_alias")
@app.post( @app.post(
@ -295,7 +298,7 @@ def test_optional_alias_by_alias(path: str):
"/optional-bytes-validation-alias", operation_id="optional_bytes_validation_alias" "/optional-bytes-validation-alias", operation_id="optional_bytes_validation_alias"
) )
def read_optional_bytes_validation_alias( def read_optional_bytes_validation_alias(
p: Optional[bytes] = File(None, validation_alias="p_val_alias"), p: Annotated[Optional[bytes], File(validation_alias="p_val_alias")] = None,
): ):
return {"file_size": len(p) if p else None} return {"file_size": len(p) if p else None}
@ -305,13 +308,13 @@ def read_optional_bytes_validation_alias(
operation_id="optional_uploadfile_validation_alias", operation_id="optional_uploadfile_validation_alias",
) )
def read_optional_uploadfile_validation_alias( def read_optional_uploadfile_validation_alias(
p: Optional[UploadFile] = File(None, validation_alias="p_val_alias"), p: Annotated[Optional[UploadFile], File(validation_alias="p_val_alias")] = None,
): ):
return {"file_size": p.size if p else None} return {"file_size": p.size if p else None}
class FormModelOptionalBytesValidationAlias(BaseModel): class FormModelOptionalBytesValidationAlias(BaseModel):
p: Optional[bytes] = File(None, validation_alias="p_val_alias") p: Optional[bytes] = File(default=None, validation_alias="p_val_alias")
@app.post( @app.post(
@ -327,7 +330,7 @@ def read_model_optional_bytes_validation_alias(
class FormModelOptionalUploadFileValidationAlias(BaseModel): class FormModelOptionalUploadFileValidationAlias(BaseModel):
p: Optional[UploadFile] = File(None, validation_alias="p_val_alias") p: Optional[UploadFile] = File(default=None, validation_alias="p_val_alias")
@app.post( @app.post(
@ -458,7 +461,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
operation_id="optional_bytes_alias_and_validation_alias", operation_id="optional_bytes_alias_and_validation_alias",
) )
def read_optional_bytes_alias_and_validation_alias( def read_optional_bytes_alias_and_validation_alias(
p: Optional[bytes] = File(None, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
Optional[bytes], File(alias="p_alias", validation_alias="p_val_alias")
] = None,
): ):
return {"file_size": len(p) if p else None} return {"file_size": len(p) if p else None}
@ -468,15 +473,17 @@ def read_optional_bytes_alias_and_validation_alias(
operation_id="optional_uploadfile_alias_and_validation_alias", operation_id="optional_uploadfile_alias_and_validation_alias",
) )
def read_optional_uploadfile_alias_and_validation_alias( def read_optional_uploadfile_alias_and_validation_alias(
p: Optional[UploadFile] = File( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"file_size": p.size if p else None} return {"file_size": p.size if p else None}
class FormModelOptionalBytesAliasAndValidationAlias(BaseModel): class FormModelOptionalBytesAliasAndValidationAlias(BaseModel):
p: Optional[bytes] = File(None, alias="p_alias", validation_alias="p_val_alias") p: Optional[bytes] = File(
default=None, alias="p_alias", validation_alias="p_val_alias"
)
@app.post( @app.post(
@ -493,7 +500,7 @@ def read_model_optional_bytes_alias_and_validation_alias(
class FormModelOptionalUploadFileAliasAndValidationAlias(BaseModel): class FormModelOptionalUploadFileAliasAndValidationAlias(BaseModel):
p: Optional[UploadFile] = File( p: Optional[UploadFile] = File(
None, alias="p_alias", validation_alias="p_val_alias" default=None, alias="p_alias", validation_alias="p_val_alias"
) )

46
tests/test_request_params/test_file/test_optional_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, File, Form, UploadFile
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,17 +19,19 @@ app = FastAPI()
@app.post("/optional-list-bytes") @app.post("/optional-list-bytes")
async def read_optional_list_bytes(p: Optional[List[bytes]] = File(None)): async def read_optional_list_bytes(p: Annotated[Optional[List[bytes]], File()] = None):
return {"file_size": [len(file) for file in p] if p else None} return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile") @app.post("/optional-list-uploadfile")
async def read_optional_list_uploadfile(p: Optional[List[UploadFile]] = File(None)): async def read_optional_list_uploadfile(
p: Annotated[Optional[List[UploadFile]], File()] = None,
):
return {"file_size": [file.size for file in p] if p else None} return {"file_size": [file.size for file in p] if p else None}
class FormModelOptionalListBytes(BaseModel): class FormModelOptionalListBytes(BaseModel):
p: Optional[List[bytes]] = File(None) p: Optional[List[bytes]] = File(default=None)
@app.post("/model-optional-list-bytes") @app.post("/model-optional-list-bytes")
@ -41,7 +44,7 @@ async def read_model_optional_list_bytes(
class FormModelOptionalListUploadFile(BaseModel): class FormModelOptionalListUploadFile(BaseModel):
p: Optional[List[UploadFile]] = File(None) p: Optional[List[UploadFile]] = File(default=None)
@app.post("/model-optional-list-uploadfile") @app.post("/model-optional-list-uploadfile")
@ -150,20 +153,20 @@ def test_optional_list(path: str):
@app.post("/optional-list-bytes-alias") @app.post("/optional-list-bytes-alias")
async def read_optional_list_bytes_alias( async def read_optional_list_bytes_alias(
p: Optional[List[bytes]] = File(None, alias="p_alias"), p: Annotated[Optional[List[bytes]], File(alias="p_alias")] = None,
): ):
return {"file_size": [len(file) for file in p] if p else None} return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-alias") @app.post("/optional-list-uploadfile-alias")
async def read_optional_list_uploadfile_alias( async def read_optional_list_uploadfile_alias(
p: Optional[List[UploadFile]] = File(None, alias="p_alias"), p: Annotated[Optional[List[UploadFile]], File(alias="p_alias")] = None,
): ):
return {"file_size": [file.size for file in p] if p else None} return {"file_size": [file.size for file in p] if p else None}
class FormModelOptionalListBytesAlias(BaseModel): class FormModelOptionalListBytesAlias(BaseModel):
p: Optional[List[bytes]] = File(None, alias="p_alias") p: Optional[List[bytes]] = File(default=None, alias="p_alias")
@app.post("/model-optional-list-bytes-alias") @app.post("/model-optional-list-bytes-alias")
@ -176,7 +179,7 @@ async def read_model_optional_list_bytes_alias(
class FormModelOptionalListUploadFileAlias(BaseModel): class FormModelOptionalListUploadFileAlias(BaseModel):
p: Optional[List[UploadFile]] = File(None, alias="p_alias") p: Optional[List[UploadFile]] = File(default=None, alias="p_alias")
@app.post("/model-optional-list-uploadfile-alias") @app.post("/model-optional-list-uploadfile-alias")
@ -335,20 +338,22 @@ def test_optional_list_alias_by_alias(path: str):
@app.post("/optional-list-bytes-validation-alias") @app.post("/optional-list-bytes-validation-alias")
def read_optional_list_bytes_validation_alias( def read_optional_list_bytes_validation_alias(
p: Optional[List[bytes]] = File(None, validation_alias="p_val_alias"), p: Annotated[Optional[List[bytes]], File(validation_alias="p_val_alias")] = None,
): ):
return {"file_size": [len(file) for file in p] if p else None} return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-validation-alias") @app.post("/optional-list-uploadfile-validation-alias")
def read_optional_list_uploadfile_validation_alias( def read_optional_list_uploadfile_validation_alias(
p: Optional[List[UploadFile]] = File(None, validation_alias="p_val_alias"), p: Annotated[
Optional[List[UploadFile]], File(validation_alias="p_val_alias")
] = None,
): ):
return {"file_size": [file.size for file in p] if p else None} return {"file_size": [file.size for file in p] if p else None}
class FormModelOptionalListBytesValidationAlias(BaseModel): class FormModelOptionalListBytesValidationAlias(BaseModel):
p: Optional[List[bytes]] = File(None, validation_alias="p_val_alias") p: Optional[List[bytes]] = File(default=None, validation_alias="p_val_alias")
@app.post("/model-optional-list-bytes-validation-alias") @app.post("/model-optional-list-bytes-validation-alias")
@ -361,7 +366,7 @@ def read_model_optional_list_bytes_validation_alias(
class FormModelOptionalListUploadFileValidationAlias(BaseModel): class FormModelOptionalListUploadFileValidationAlias(BaseModel):
p: Optional[List[UploadFile]] = File(None, validation_alias="p_val_alias") p: Optional[List[UploadFile]] = File(default=None, validation_alias="p_val_alias")
@app.post("/model-optional-list-uploadfile-validation-alias") @app.post("/model-optional-list-uploadfile-validation-alias")
@ -500,25 +505,26 @@ def test_optional_validation_alias_by_validation_alias(path: str):
@app.post("/optional-list-bytes-alias-and-validation-alias") @app.post("/optional-list-bytes-alias-and-validation-alias")
def read_optional_list_bytes_alias_and_validation_alias( def read_optional_list_bytes_alias_and_validation_alias(
p: Optional[List[bytes]] = File( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[List[bytes]], File(alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"file_size": [len(file) for file in p] if p else None} return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-alias-and-validation-alias") @app.post("/optional-list-uploadfile-alias-and-validation-alias")
def read_optional_list_uploadfile_alias_and_validation_alias( def read_optional_list_uploadfile_alias_and_validation_alias(
p: Optional[List[UploadFile]] = File( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[List[UploadFile]],
), File(alias="p_alias", validation_alias="p_val_alias"),
] = None,
): ):
return {"file_size": [file.size for file in p] if p else None} return {"file_size": [file.size for file in p] if p else None}
class FormModelOptionalListBytesAliasAndValidationAlias(BaseModel): class FormModelOptionalListBytesAliasAndValidationAlias(BaseModel):
p: Optional[List[bytes]] = File( p: Optional[List[bytes]] = File(
None, alias="p_alias", validation_alias="p_val_alias" default=None, alias="p_alias", validation_alias="p_val_alias"
) )
@ -533,7 +539,7 @@ def read_model_optional_list_bytes_alias_and_validation_alias(
class FormModelOptionalListUploadFileAliasAndValidationAlias(BaseModel): class FormModelOptionalListUploadFileAliasAndValidationAlias(BaseModel):
p: Optional[List[UploadFile]] = File( p: Optional[List[UploadFile]] = File(
None, alias="p_alias", validation_alias="p_val_alias" default=None, alias="p_alias", validation_alias="p_val_alias"
) )

35
tests/test_request_params/test_file/test_required.py

@ -4,6 +4,7 @@ from fastapi import FastAPI, File, Form, UploadFile
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -16,17 +17,17 @@ app = FastAPI()
@app.post("/required-bytes", operation_id="required_bytes") @app.post("/required-bytes", operation_id="required_bytes")
async def read_required_bytes(p: bytes = File(...)): async def read_required_bytes(p: Annotated[bytes, File()]):
return {"file_size": len(p)} return {"file_size": len(p)}
@app.post("/required-uploadfile", operation_id="required_uploadfile") @app.post("/required-uploadfile", operation_id="required_uploadfile")
async def read_required_uploadfile(p: UploadFile = File(...)): async def read_required_uploadfile(p: Annotated[UploadFile, File()]):
return {"file_size": p.size} return {"file_size": p.size}
class FormModelRequiredBytes(BaseModel): class FormModelRequiredBytes(BaseModel):
p: bytes = File(...) p: bytes = File()
@app.post("/model-required-bytes", operation_id="model_required_bytes") @app.post("/model-required-bytes", operation_id="model_required_bytes")
@ -39,7 +40,7 @@ async def read_model_required_bytes(
class FormModelRequiredUploadFile(BaseModel): class FormModelRequiredUploadFile(BaseModel):
p: UploadFile = File(...) p: UploadFile = File()
@app.post("/model-required-uploadfile", operation_id="model_required_uploadfile") @app.post("/model-required-uploadfile", operation_id="model_required_uploadfile")
@ -133,17 +134,19 @@ def test_required(path: str):
@app.post("/required-bytes-alias", operation_id="required_bytes_alias") @app.post("/required-bytes-alias", operation_id="required_bytes_alias")
async def read_required_bytes_alias(p: bytes = File(..., alias="p_alias")): async def read_required_bytes_alias(p: Annotated[bytes, File(alias="p_alias")]):
return {"file_size": len(p)} return {"file_size": len(p)}
@app.post("/required-uploadfile-alias", operation_id="required_uploadfile_alias") @app.post("/required-uploadfile-alias", operation_id="required_uploadfile_alias")
async def read_required_uploadfile_alias(p: UploadFile = File(..., alias="p_alias")): async def read_required_uploadfile_alias(
p: Annotated[UploadFile, File(alias="p_alias")],
):
return {"file_size": p.size} return {"file_size": p.size}
class FormModelRequiredBytesAlias(BaseModel): class FormModelRequiredBytesAlias(BaseModel):
p: bytes = File(..., alias="p_alias") p: bytes = File(alias="p_alias")
@app.post("/model-required-bytes-alias", operation_id="model_required_bytes_alias") @app.post("/model-required-bytes-alias", operation_id="model_required_bytes_alias")
@ -156,7 +159,7 @@ async def read_model_required_bytes_alias(
class FormModelRequiredUploadFileAlias(BaseModel): class FormModelRequiredUploadFileAlias(BaseModel):
p: UploadFile = File(..., alias="p_alias") p: UploadFile = File(alias="p_alias")
@app.post( @app.post(
@ -353,7 +356,7 @@ def test_required_alias_by_alias(path: str):
"/required-bytes-validation-alias", operation_id="required_bytes_validation_alias" "/required-bytes-validation-alias", operation_id="required_bytes_validation_alias"
) )
def read_required_bytes_validation_alias( def read_required_bytes_validation_alias(
p: bytes = File(..., validation_alias="p_val_alias"), p: Annotated[bytes, File(validation_alias="p_val_alias")],
): ):
return {"file_size": len(p)} return {"file_size": len(p)}
@ -363,13 +366,13 @@ def read_required_bytes_validation_alias(
operation_id="required_uploadfile_validation_alias", operation_id="required_uploadfile_validation_alias",
) )
def read_required_uploadfile_validation_alias( def read_required_uploadfile_validation_alias(
p: UploadFile = File(..., validation_alias="p_val_alias"), p: Annotated[UploadFile, File(validation_alias="p_val_alias")],
): ):
return {"file_size": p.size} return {"file_size": p.size}
class FormModelRequiredBytesValidationAlias(BaseModel): class FormModelRequiredBytesValidationAlias(BaseModel):
p: bytes = File(..., validation_alias="p_val_alias") p: bytes = File(validation_alias="p_val_alias")
@app.post( @app.post(
@ -385,7 +388,7 @@ def read_model_required_bytes_validation_alias(
class FormModelRequiredUploadFileValidationAlias(BaseModel): class FormModelRequiredUploadFileValidationAlias(BaseModel):
p: UploadFile = File(..., validation_alias="p_val_alias") p: UploadFile = File(validation_alias="p_val_alias")
@app.post( @app.post(
@ -540,7 +543,7 @@ def test_required_validation_alias_by_validation_alias(path: str):
operation_id="required_bytes_alias_and_validation_alias", operation_id="required_bytes_alias_and_validation_alias",
) )
def read_required_bytes_alias_and_validation_alias( def read_required_bytes_alias_and_validation_alias(
p: bytes = File(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[bytes, File(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"file_size": len(p)} return {"file_size": len(p)}
@ -550,13 +553,13 @@ def read_required_bytes_alias_and_validation_alias(
operation_id="required_uploadfile_alias_and_validation_alias", operation_id="required_uploadfile_alias_and_validation_alias",
) )
def read_required_uploadfile_alias_and_validation_alias( def read_required_uploadfile_alias_and_validation_alias(
p: UploadFile = File(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[UploadFile, File(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"file_size": p.size} return {"file_size": p.size}
class FormModelRequiredBytesAliasAndValidationAlias(BaseModel): class FormModelRequiredBytesAliasAndValidationAlias(BaseModel):
p: bytes = File(..., alias="p_alias", validation_alias="p_val_alias") p: bytes = File(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(
@ -572,7 +575,7 @@ def read_model_required_bytes_alias_and_validation_alias(
class FormModelRequiredUploadFileAliasAndValidationAlias(BaseModel): class FormModelRequiredUploadFileAliasAndValidationAlias(BaseModel):
p: UploadFile = File(..., alias="p_alias", validation_alias="p_val_alias") p: UploadFile = File(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

15
tests/test_request_params/test_form/test_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,7 @@ app = FastAPI()
@app.post("/required-list-str", operation_id="required_list_str") @app.post("/required-list-str", operation_id="required_list_str")
async def read_required_list_str(p: List[str] = Form(...)): async def read_required_list_str(p: Annotated[List[str], Form()]):
return {"p": p} return {"p": p}
@ -101,12 +102,12 @@ def test_required_list_str(path: str):
@app.post("/required-list-alias", operation_id="required_list_alias") @app.post("/required-list-alias", operation_id="required_list_alias")
async def read_required_list_alias(p: List[str] = Form(..., alias="p_alias")): async def read_required_list_alias(p: Annotated[List[str], Form(alias="p_alias")]):
return {"p": p} return {"p": p}
class FormModelRequiredListAlias(BaseModel): class FormModelRequiredListAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias") p: List[str] = Field(alias="p_alias")
@app.post("/model-required-list-alias", operation_id="model_required_list_alias") @app.post("/model-required-list-alias", operation_id="model_required_list_alias")
@ -245,13 +246,13 @@ def test_required_list_alias_by_alias(path: str):
"/required-list-validation-alias", operation_id="required_list_validation_alias" "/required-list-validation-alias", operation_id="required_list_validation_alias"
) )
def read_required_list_validation_alias( def read_required_list_validation_alias(
p: List[str] = Form(..., validation_alias="p_val_alias"), p: Annotated[List[str], Form(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredListValidationAlias(BaseModel): class FormModelRequiredListValidationAlias(BaseModel):
p: List[str] = Field(..., validation_alias="p_val_alias") p: List[str] = Field(validation_alias="p_val_alias")
@app.post( @app.post(
@ -370,13 +371,13 @@ def test_required_list_validation_alias_by_validation_alias(path: str):
operation_id="required_list_alias_and_validation_alias", operation_id="required_list_alias_and_validation_alias",
) )
def read_required_list_alias_and_validation_alias( def read_required_list_alias_and_validation_alias(
p: List[str] = Form(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[List[str], Form(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredListAliasAndValidationAlias(BaseModel): class FormModelRequiredListAliasAndValidationAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias", validation_alias="p_val_alias") p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

15
tests/test_request_params/test_form/test_optional_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,9 @@ app = FastAPI()
@app.post("/optional-list-str", operation_id="optional_list_str") @app.post("/optional-list-str", operation_id="optional_list_str")
async def read_optional_list_str(p: Optional[List[str]] = Form(None)): async def read_optional_list_str(
p: Annotated[Optional[List[str]], Form()] = None,
):
return {"p": p} return {"p": p}
@ -93,7 +96,7 @@ def test_optional_list_str(path: str):
@app.post("/optional-list-alias", operation_id="optional_list_alias") @app.post("/optional-list-alias", operation_id="optional_list_alias")
async def read_optional_list_alias( async def read_optional_list_alias(
p: Optional[List[str]] = Form(None, alias="p_alias"), p: Annotated[Optional[List[str]], Form(alias="p_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -197,7 +200,7 @@ def test_optional_list_alias_by_alias(path: str):
"/optional-list-validation-alias", operation_id="optional_list_validation_alias" "/optional-list-validation-alias", operation_id="optional_list_validation_alias"
) )
def read_optional_list_validation_alias( def read_optional_list_validation_alias(
p: Optional[List[str]] = Form(None, validation_alias="p_val_alias"), p: Annotated[Optional[List[str]], Form(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -311,9 +314,9 @@ def test_optional_list_validation_alias_by_validation_alias(path: str):
operation_id="optional_list_alias_and_validation_alias", operation_id="optional_list_alias_and_validation_alias",
) )
def read_optional_list_alias_and_validation_alias( def read_optional_list_alias_and_validation_alias(
p: Optional[List[str]] = Form( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[List[str]], Form(alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"p": p} return {"p": p}

13
tests/test_request_params/test_form/test_optional_str.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -18,7 +19,7 @@ app = FastAPI()
@app.post("/optional-str", operation_id="optional_str") @app.post("/optional-str", operation_id="optional_str")
async def read_optional_str(p: Optional[str] = Form(None)): async def read_optional_str(p: Annotated[Optional[str], Form()] = None):
return {"p": p} return {"p": p}
@ -89,7 +90,9 @@ def test_optional_str(path: str):
@app.post("/optional-alias", operation_id="optional_alias") @app.post("/optional-alias", operation_id="optional_alias")
async def read_optional_alias(p: Optional[str] = Form(None, alias="p_alias")): async def read_optional_alias(
p: Annotated[Optional[str], Form(alias="p_alias")] = None,
):
return {"p": p} return {"p": p}
@ -183,7 +186,7 @@ def test_optional_alias_by_alias(path: str):
@app.post("/optional-validation-alias", operation_id="optional_validation_alias") @app.post("/optional-validation-alias", operation_id="optional_validation_alias")
def read_optional_validation_alias( def read_optional_validation_alias(
p: Optional[str] = Form(None, validation_alias="p_val_alias"), p: Annotated[Optional[str], Form(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -290,7 +293,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
operation_id="optional_alias_and_validation_alias", operation_id="optional_alias_and_validation_alias",
) )
def read_optional_alias_and_validation_alias( def read_optional_alias_and_validation_alias(
p: Optional[str] = Form(None, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
Optional[str], Form(alias="p_alias", validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}

15
tests/test_request_params/test_form/test_required_str.py

@ -4,6 +4,7 @@ from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -16,7 +17,7 @@ app = FastAPI()
@app.post("/required-str", operation_id="required_str") @app.post("/required-str", operation_id="required_str")
async def read_required_str(p: str = Form(...)): async def read_required_str(p: Annotated[str, Form()]):
return {"p": p} return {"p": p}
@ -96,12 +97,12 @@ def test_required_str(path: str):
@app.post("/required-alias", operation_id="required_alias") @app.post("/required-alias", operation_id="required_alias")
async def read_required_alias(p: str = Form(..., alias="p_alias")): async def read_required_alias(p: Annotated[str, Form(alias="p_alias")]):
return {"p": p} return {"p": p}
class FormModelRequiredAlias(BaseModel): class FormModelRequiredAlias(BaseModel):
p: str = Field(..., alias="p_alias") p: str = Field(alias="p_alias")
@app.post("/model-required-alias", operation_id="model_required_alias") @app.post("/model-required-alias", operation_id="model_required_alias")
@ -221,13 +222,13 @@ def test_required_alias_by_alias(path: str):
@app.post("/required-validation-alias", operation_id="required_validation_alias") @app.post("/required-validation-alias", operation_id="required_validation_alias")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Form(..., validation_alias="p_val_alias"), p: Annotated[str, Form(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredValidationAlias(BaseModel): class FormModelRequiredValidationAlias(BaseModel):
p: str = Field(..., validation_alias="p_val_alias") p: str = Field(validation_alias="p_val_alias")
@app.post( @app.post(
@ -348,13 +349,13 @@ def test_required_validation_alias_by_validation_alias(path: str):
operation_id="required_alias_and_validation_alias", operation_id="required_alias_and_validation_alias",
) )
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Form(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[str, Form(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class FormModelRequiredAliasAndValidationAlias(BaseModel): class FormModelRequiredAliasAndValidationAlias(BaseModel):
p: str = Field(..., alias="p_alias", validation_alias="p_val_alias") p: str = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post( @app.post(

15
tests/test_request_params/test_header/test_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, Header
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -16,7 +17,7 @@ app = FastAPI()
@app.get("/required-list-str") @app.get("/required-list-str")
async def read_required_list_str(p: List[str] = Header(...)): async def read_required_list_str(p: Annotated[List[str], Header()]):
return {"p": p} return {"p": p}
@ -96,12 +97,12 @@ def test_required_list_str(path: str):
@app.get("/required-list-alias") @app.get("/required-list-alias")
async def read_required_list_alias(p: List[str] = Header(..., alias="p_alias")): async def read_required_list_alias(p: Annotated[List[str], Header(alias="p_alias")]):
return {"p": p} return {"p": p}
class HeaderModelRequiredListAlias(BaseModel): class HeaderModelRequiredListAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias") p: List[str] = Field(alias="p_alias")
@app.get("/model-required-list-alias") @app.get("/model-required-list-alias")
@ -232,13 +233,13 @@ def test_required_list_alias_by_alias(path: str):
@app.get("/required-list-validation-alias") @app.get("/required-list-validation-alias")
def read_required_list_validation_alias( def read_required_list_validation_alias(
p: List[str] = Header(..., validation_alias="p_val_alias"), p: Annotated[List[str], Header(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class HeaderModelRequiredListValidationAlias(BaseModel): class HeaderModelRequiredListValidationAlias(BaseModel):
p: List[str] = Field(..., validation_alias="p_val_alias") p: List[str] = Field(validation_alias="p_val_alias")
@app.get("/model-required-list-validation-alias") @app.get("/model-required-list-validation-alias")
@ -349,13 +350,13 @@ def test_required_list_validation_alias_by_validation_alias(path: str):
@app.get("/required-list-alias-and-validation-alias") @app.get("/required-list-alias-and-validation-alias")
def read_required_list_alias_and_validation_alias( def read_required_list_alias_and_validation_alias(
p: List[str] = Header(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[List[str], Header(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class HeaderModelRequiredListAliasAndValidationAlias(BaseModel): class HeaderModelRequiredListAliasAndValidationAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias", validation_alias="p_val_alias") p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-list-alias-and-validation-alias") @app.get("/model-required-list-alias-and-validation-alias")

15
tests/test_request_params/test_header/test_optional_list.py

@ -5,6 +5,7 @@ from dirty_equals import IsDict
from fastapi import FastAPI, Header from fastapi import FastAPI, Header
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -15,7 +16,9 @@ app = FastAPI()
@app.get("/optional-list-str") @app.get("/optional-list-str")
async def read_optional_list_str(p: Optional[List[str]] = Header(None)): async def read_optional_list_str(
p: Annotated[Optional[List[str]], Header()] = None,
):
return {"p": p} return {"p": p}
@ -88,7 +91,7 @@ def test_optional_list_str(path: str):
@app.get("/optional-list-alias") @app.get("/optional-list-alias")
async def read_optional_list_alias( async def read_optional_list_alias(
p: Optional[List[str]] = Header(None, alias="p_alias"), p: Annotated[Optional[List[str]], Header(alias="p_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -185,7 +188,7 @@ def test_optional_list_alias_by_alias(path: str):
@app.get("/optional-list-validation-alias") @app.get("/optional-list-validation-alias")
def read_optional_list_validation_alias( def read_optional_list_validation_alias(
p: Optional[List[str]] = Header(None, validation_alias="p_val_alias"), p: Annotated[Optional[List[str]], Header(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -279,9 +282,9 @@ def test_optional_list_validation_alias_by_validation_alias(path: str):
@app.get("/optional-list-alias-and-validation-alias") @app.get("/optional-list-alias-and-validation-alias")
def read_optional_list_alias_and_validation_alias( def read_optional_list_alias_and_validation_alias(
p: Optional[List[str]] = Header( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[List[str]], Header(alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"p": p} return {"p": p}

13
tests/test_request_params/test_header/test_optional_str.py

@ -5,6 +5,7 @@ from dirty_equals import IsDict
from fastapi import FastAPI, Header from fastapi import FastAPI, Header
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -15,7 +16,7 @@ app = FastAPI()
@app.get("/optional-str") @app.get("/optional-str")
async def read_optional_str(p: Optional[str] = Header(None)): async def read_optional_str(p: Annotated[Optional[str], Header()] = None):
return {"p": p} return {"p": p}
@ -84,7 +85,9 @@ def test_optional_str(path: str):
@app.get("/optional-alias") @app.get("/optional-alias")
async def read_optional_alias(p: Optional[str] = Header(None, alias="p_alias")): async def read_optional_alias(
p: Annotated[Optional[str], Header(alias="p_alias")] = None,
):
return {"p": p} return {"p": p}
@ -171,7 +174,7 @@ def test_optional_alias_by_alias(path: str):
@app.get("/optional-validation-alias") @app.get("/optional-validation-alias")
def read_optional_validation_alias( def read_optional_validation_alias(
p: Optional[str] = Header(None, validation_alias="p_val_alias"), p: Annotated[Optional[str], Header(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -261,7 +264,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
@app.get("/optional-alias-and-validation-alias") @app.get("/optional-alias-and-validation-alias")
def read_optional_alias_and_validation_alias( def read_optional_alias_and_validation_alias(
p: Optional[str] = Header(None, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
Optional[str], Header(alias="p_alias", validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}

15
tests/test_request_params/test_header/test_required_str.py

@ -4,6 +4,7 @@ from fastapi import FastAPI, Header
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -14,7 +15,7 @@ app = FastAPI()
@app.get("/required-str") @app.get("/required-str")
async def read_required_str(p: str = Header(...)): async def read_required_str(p: Annotated[str, Header()]):
return {"p": p} return {"p": p}
@ -91,12 +92,12 @@ def test_required_str(path: str):
@app.get("/required-alias") @app.get("/required-alias")
async def read_required_alias(p: str = Header(..., alias="p_alias")): async def read_required_alias(p: Annotated[str, Header(alias="p_alias")]):
return {"p": p} return {"p": p}
class HeaderModelRequiredAlias(BaseModel): class HeaderModelRequiredAlias(BaseModel):
p: str = Field(..., alias="p_alias") p: str = Field(alias="p_alias")
@app.get("/model-required-alias") @app.get("/model-required-alias")
@ -221,13 +222,13 @@ def test_required_alias_by_alias(path: str):
@app.get("/required-validation-alias") @app.get("/required-validation-alias")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Header(..., validation_alias="p_val_alias"), p: Annotated[str, Header(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class HeaderModelRequiredValidationAlias(BaseModel): class HeaderModelRequiredValidationAlias(BaseModel):
p: str = Field(..., validation_alias="p_val_alias") p: str = Field(validation_alias="p_val_alias")
@app.get("/model-required-validation-alias") @app.get("/model-required-validation-alias")
@ -341,13 +342,13 @@ def test_required_validation_alias_by_validation_alias(path: str):
@app.get("/required-alias-and-validation-alias") @app.get("/required-alias-and-validation-alias")
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Header(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[str, Header(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class HeaderModelRequiredAliasAndValidationAlias(BaseModel): class HeaderModelRequiredAliasAndValidationAlias(BaseModel):
p: str = Field(..., alias="p_alias", validation_alias="p_val_alias") p: str = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-alias-and-validation-alias") @app.get("/model-required-alias-and-validation-alias")

9
tests/test_request_params/test_path/test_required_str.py

@ -1,6 +1,7 @@
import pytest import pytest
from fastapi import FastAPI, Path from fastapi import FastAPI, Path
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -8,25 +9,25 @@ app = FastAPI()
@app.get("/required-str/{p}") @app.get("/required-str/{p}")
async def read_required_str(p: str = Path(...)): async def read_required_str(p: Annotated[str, Path()]):
return {"p": p} return {"p": p}
@app.get("/required-alias/{p_alias}") @app.get("/required-alias/{p_alias}")
async def read_required_alias(p: str = Path(..., alias="p_alias")): async def read_required_alias(p: Annotated[str, Path(alias="p_alias")]):
return {"p": p} return {"p": p}
@app.get("/required-validation-alias/{p_val_alias}") @app.get("/required-validation-alias/{p_val_alias}")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Path(..., validation_alias="p_val_alias"), p: Annotated[str, Path(validation_alias="p_val_alias")],
): ):
return {"p": p} # pragma: no cover return {"p": p} # pragma: no cover
@app.get("/required-alias-and-validation-alias/{p_val_alias}") @app.get("/required-alias-and-validation-alias/{p_val_alias}")
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Path(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[str, Path(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} # pragma: no cover return {"p": p} # pragma: no cover

15
tests/test_request_params/test_query/test_list.py

@ -6,6 +6,7 @@ from fastapi import FastAPI, Query
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -16,7 +17,7 @@ app = FastAPI()
@app.get("/required-list-str") @app.get("/required-list-str")
async def read_required_list_str(p: List[str] = Query(...)): async def read_required_list_str(p: Annotated[List[str], Query()]):
return {"p": p} return {"p": p}
@ -96,12 +97,12 @@ def test_required_list_str(path: str):
@app.get("/required-list-alias") @app.get("/required-list-alias")
async def read_required_list_alias(p: List[str] = Query(..., alias="p_alias")): async def read_required_list_alias(p: Annotated[List[str], Query(alias="p_alias")]):
return {"p": p} return {"p": p}
class QueryModelRequiredListAlias(BaseModel): class QueryModelRequiredListAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias") p: List[str] = Field(alias="p_alias")
@app.get("/model-required-list-alias") @app.get("/model-required-list-alias")
@ -232,13 +233,13 @@ def test_required_list_alias_by_alias(path: str):
@app.get("/required-list-validation-alias") @app.get("/required-list-validation-alias")
def read_required_list_validation_alias( def read_required_list_validation_alias(
p: List[str] = Query(..., validation_alias="p_val_alias"), p: Annotated[List[str], Query(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class QueryModelRequiredListValidationAlias(BaseModel): class QueryModelRequiredListValidationAlias(BaseModel):
p: List[str] = Field(..., validation_alias="p_val_alias") p: List[str] = Field(validation_alias="p_val_alias")
@app.get("/model-required-list-validation-alias") @app.get("/model-required-list-validation-alias")
@ -347,13 +348,13 @@ def test_required_list_validation_alias_by_validation_alias(path: str):
@app.get("/required-list-alias-and-validation-alias") @app.get("/required-list-alias-and-validation-alias")
def read_required_list_alias_and_validation_alias( def read_required_list_alias_and_validation_alias(
p: List[str] = Query(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[List[str], Query(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class QueryModelRequiredListAliasAndValidationAlias(BaseModel): class QueryModelRequiredListAliasAndValidationAlias(BaseModel):
p: List[str] = Field(..., alias="p_alias", validation_alias="p_val_alias") p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-list-alias-and-validation-alias") @app.get("/model-required-list-alias-and-validation-alias")

15
tests/test_request_params/test_query/test_optional_list.py

@ -5,6 +5,7 @@ from dirty_equals import IsDict
from fastapi import FastAPI, Query from fastapi import FastAPI, Query
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -15,7 +16,9 @@ app = FastAPI()
@app.get("/optional-list-str") @app.get("/optional-list-str")
async def read_optional_list_str(p: Optional[List[str]] = Query(None)): async def read_optional_list_str(
p: Annotated[Optional[List[str]], Query()] = None,
):
return {"p": p} return {"p": p}
@ -88,7 +91,7 @@ def test_optional_list_str(path: str):
@app.get("/optional-list-alias") @app.get("/optional-list-alias")
async def read_optional_list_alias( async def read_optional_list_alias(
p: Optional[List[str]] = Query(None, alias="p_alias"), p: Annotated[Optional[List[str]], Query(alias="p_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -185,7 +188,7 @@ def test_optional_list_alias_by_alias(path: str):
@app.get("/optional-list-validation-alias") @app.get("/optional-list-validation-alias")
def read_optional_list_validation_alias( def read_optional_list_validation_alias(
p: Optional[List[str]] = Query(None, validation_alias="p_val_alias"), p: Annotated[Optional[List[str]], Query(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -277,9 +280,9 @@ def test_optional_list_validation_alias_by_validation_alias(path: str):
@app.get("/optional-list-alias-and-validation-alias") @app.get("/optional-list-alias-and-validation-alias")
def read_optional_list_alias_and_validation_alias( def read_optional_list_alias_and_validation_alias(
p: Optional[List[str]] = Query( p: Annotated[
None, alias="p_alias", validation_alias="p_val_alias" Optional[List[str]], Query(alias="p_alias", validation_alias="p_val_alias")
), ] = None,
): ):
return {"p": p} return {"p": p}

11
tests/test_request_params/test_query/test_optional_str.py

@ -5,6 +5,7 @@ from dirty_equals import IsDict
from fastapi import FastAPI, Query from fastapi import FastAPI, Query
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -84,7 +85,9 @@ def test_optional_str(path: str):
@app.get("/optional-alias") @app.get("/optional-alias")
async def read_optional_alias(p: Optional[str] = Query(None, alias="p_alias")): async def read_optional_alias(
p: Annotated[Optional[str], Query(alias="p_alias")] = None,
):
return {"p": p} return {"p": p}
@ -171,7 +174,7 @@ def test_optional_alias_by_alias(path: str):
@app.get("/optional-validation-alias") @app.get("/optional-validation-alias")
def read_optional_validation_alias( def read_optional_validation_alias(
p: Optional[str] = Query(None, validation_alias="p_val_alias"), p: Annotated[Optional[str], Query(validation_alias="p_val_alias")] = None,
): ):
return {"p": p} return {"p": p}
@ -261,7 +264,9 @@ def test_optional_validation_alias_by_validation_alias(path: str):
@app.get("/optional-alias-and-validation-alias") @app.get("/optional-alias-and-validation-alias")
def read_optional_alias_and_validation_alias( def read_optional_alias_and_validation_alias(
p: Optional[str] = Query(None, alias="p_alias", validation_alias="p_val_alias"), p: Annotated[
Optional[str], Query(alias="p_alias", validation_alias="p_val_alias")
] = None,
): ):
return {"p": p} return {"p": p}

13
tests/test_request_params/test_query/test_required_str.py

@ -4,6 +4,7 @@ from fastapi import FastAPI, Query
from fastapi._compat import PYDANTIC_V2 from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing_extensions import Annotated
from tests.utils import needs_pydanticv2 from tests.utils import needs_pydanticv2
@ -91,12 +92,12 @@ def test_required_str(path: str):
@app.get("/required-alias") @app.get("/required-alias")
async def read_required_alias(p: str = Query(..., alias="p_alias")): async def read_required_alias(p: Annotated[str, Query(alias="p_alias")]):
return {"p": p} return {"p": p}
class QueryModelRequiredAlias(BaseModel): class QueryModelRequiredAlias(BaseModel):
p: str = Field(..., alias="p_alias") p: str = Field(alias="p_alias")
@app.get("/model-required-alias") @app.get("/model-required-alias")
@ -224,13 +225,13 @@ def test_required_alias_by_alias(path: str):
@app.get("/required-validation-alias") @app.get("/required-validation-alias")
def read_required_validation_alias( def read_required_validation_alias(
p: str = Query(..., validation_alias="p_val_alias"), p: Annotated[str, Query(validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class QueryModelRequiredValidationAlias(BaseModel): class QueryModelRequiredValidationAlias(BaseModel):
p: str = Field(..., validation_alias="p_val_alias") p: str = Field(validation_alias="p_val_alias")
@app.get("/model-required-validation-alias") @app.get("/model-required-validation-alias")
@ -344,13 +345,13 @@ def test_required_validation_alias_by_validation_alias(path: str):
@app.get("/required-alias-and-validation-alias") @app.get("/required-alias-and-validation-alias")
def read_required_alias_and_validation_alias( def read_required_alias_and_validation_alias(
p: str = Query(..., alias="p_alias", validation_alias="p_val_alias"), p: Annotated[str, Query(alias="p_alias", validation_alias="p_val_alias")],
): ):
return {"p": p} return {"p": p}
class QueryModelRequiredAliasAndValidationAlias(BaseModel): class QueryModelRequiredAliasAndValidationAlias(BaseModel):
p: str = Field(..., alias="p_alias", validation_alias="p_val_alias") p: str = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-alias-and-validation-alias") @app.get("/model-required-alias-and-validation-alias")

Loading…
Cancel
Save