-
First Check
Commit to Help
Example Codefrom typing import Annotated
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, ConfigDict, Field
app = FastAPI()
class Raw(BaseModel):
by_name: str = Field(alias="byName")
class Populate(BaseModel):
by_name: str = Field(alias="byName")
model_config = ConfigDict(populate_by_name=True)
class NoAlias(BaseModel):
by_name: str
@app.get("/raw")
def raw(e: Annotated[Raw, Query()]):
return e
@app.get("/populate")
def populate(c: Annotated[Populate, Query()]):
return c
@app.get("/no-alias")
def no_alias(n: Annotated[NoAlias, Query()]):
return n
client = TestClient(app)
def test_raw():
# this is unexpected
response = client.get("/raw", params={"by_name": "nok"})
assert response.status_code == 422
response = client.get("/raw", params={"byName": "nok"})
assert response.status_code == 422
def test_populate_by_name():
response = client.get("/populate", params={"byName": "ok"})
assert response.status_code == 200
response = client.get("/populate", params={"by_name": "nok"})
assert response.status_code == 422
def test_no_alias():
response = client.get("/no-alias", params={"byName": "ok"})
assert response.status_code == 422
response = client.get("/no-alias", params={"by_name": "nok"})
assert response.status_code == 200DescriptionAt least the client.get("/raw", params={"byName": "nok"})because Raw(byName="ok")
Raw.model_validate({"byName": "ok"})
try:
Raw.model_validate({"by_name": "nok"})
except ValidationError:
passOperating SystemmacOS Operating System DetailsNo response FastAPI Version0.115.0 (main 4d6cab3) Pydantic Version2.9.2 Python VersionPython 3.12.5 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
Tracked by #12402 |
Beta Was this translation helpful? Give feedback.
-
|
The As for Detailsfrom typing import Annotated
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, ConfigDict, Field
app = FastAPI()
class Raw(BaseModel):
by_name: str = Field(default=..., alias="byName")
model_config = ConfigDict(extra="forbid")
class Populate(BaseModel):
by_name: str = Field(default=..., alias="byName")
model_config = ConfigDict(populate_by_name=True, extra="forbid")
class NoAlias(BaseModel):
by_name: str
model_config = ConfigDict(extra="forbid")
@app.get("/raw")
def raw(e: Annotated[Raw, Query()]):
return e
@app.get("/populate")
def populate(c: Annotated[Populate, Query()]):
return c
@app.get("/no-alias")
def no_alias(n: Annotated[NoAlias, Query()]):
return n
client = TestClient(app)
def test_raw():
"""
Only the alias name should work
"""
response = client.get("/raw", params={"by_name": "expect 422"})
assert response.status_code == 422
response = client.get("/raw", params={"byName": "ok"})
assert response.status_code == 200
parameters = app.openapi()["paths"]["/raw"]["get"]["parameters"]
assert len(parameters) == 1
assert parameters[0]["name"] == "byName"
def test_populate_by_name():
"""
Both the alias name and the original name should work, but only alias is in OpenAPI schema
"""
response = client.get("/populate", params={"byName": "ok"})
assert response.status_code == 200
assert response.json() == {"byName": "ok"}
response = client.get("/populate", params={"by_name": "ok"})
assert response.status_code == 200
assert response.json() == {"byName": "ok"}
parameters = app.openapi()["paths"]["/populate"]["get"]["parameters"]
assert len(parameters) == 1
assert parameters[0]["name"] == "byName"
def test_no_alias():
"""
Only the original name should work
"""
response = client.get("/no-alias", params={"byName": "expect 422"})
assert response.status_code == 422
response = client.get("/no-alias", params={"by_name": "ok"})
assert response.status_code == 200
parameters = app.openapi()["paths"]["/no-alias"]["get"]["parameters"]
assert len(parameters) == 1
assert parameters[0]["name"] == "by_name" |
Beta Was this translation helpful? Give feedback.
Tracked by #12402