Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow hyphen (-) in query parameter name using FastAPI?

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?

like image 215
Amin Ba Avatar asked Feb 11 '26 12:02

Amin Ba


1 Answers

Problem Overview

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 that BaseModel subclass will be grouped in the kwargs extra_data.

Hence the error about the missing value for extra_data query parameter.

Solution 1

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

Solution 2

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

Solution 3

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
like image 67
Chris Avatar answered Feb 13 '26 10:02

Chris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!