I have a simple application below:
from typing import Annotated
import uvicorn
from fastapi import FastAPI, Query, Depends
from pydantic import BaseModel
app = FastAPI()
class Input(BaseModel):
a: Annotated[str, Query(..., alias="your_name")]
@app.get("/")
def test(inp: Annotated[Input, Depends()]):
return f"Hello {inp.a}"
def main():
uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)
if __name__ == "__main__":
main()
curl "http://127.0.0.1:8001/?your_name=amin" returns "Hello amin"
I now change the alias from your_name to your-name.
from typing import Annotated
import uvicorn
from fastapi import FastAPI, Query, Depends
from pydantic import BaseModel
app = FastAPI()
class Input(BaseModel):
a: Annotated[str, Query(..., alias="your-name")]
@app.get("/")
def test(inp: Annotated[Input, Depends()]):
return f"Hello {inp.a}"
def main():
uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)
if __name__ == "__main__":
main()
Then curl "http://127.0.0.1:8001/?your-name=amin" returns:
{"detail":[{"loc":["query","extra_data"],"msg":"field required","type":"value_error.missing"}]}
However, hyphened alias in a simpler application is allowed.
from typing import Annotated
import uvicorn
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/")
def test(a: Annotated[str, Query(..., alias="your-name")]):
return f"Hello {a}"
def main():
uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)
if __name__ == "__main__":
main()
curl "http://127.0.0.1:8001/?your-name=amin" returns "Hello Amin"
Is this a bug? what is the problem here?
As explained here by @JarroVGIT, this is a behaviour coming from Pydantic, not FastAPI. If you looked closely at the error you posted:
{"detail":[{"loc":["query","extra_data"],"msg":"field required","type":"value_error.missing"}]}
it talks about a missing value for a query parameter named extra_data—however, there is no such a parameter defined in your BaseModel. If, in fact, you used the Swagger UI autodocs at /docs, you would see that your endpoint is expecting a required parameter named extra_data. As noted by @JarroVGIT in the linked discussion above:
Whenever you give a 'non-pythonic' alias (like with dashes/hyphens), the signature that
inspect.signature()will get from thatBaseModelsubclass will be grouped in the kwargsextra_data.
Hence the error about the missing value for extra_data query parameter.
You could wrap the Query() in a Field(), as demonstrated in this answer. Example:
from fastapi import Query, Depends
from pydantic import BaseModel, Field
class Input(BaseModel):
a: str = Field(Query(..., alias="your-name"))
@app.get("/")
def main(i: Input = Depends()):
pass
As shown in this answer and this answer, you could use a separate dependency class, instead of a BaseModel. Example:
from fastapi import Query, Depends
from dataclasses import dataclass
@dataclass
class Input:
a: str = Query(..., alias="your-name")
@app.get("/")
def main(i: Input = Depends()):
pass
Declare the query parameter directly in the endpoint, instead of using a Pydantic BaseModel. Example:
from fastapi import Query
@app.get("/")
def main(a: str = Query(..., alias="your-name")):
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With