Search code examples
pythonfastapipydantic

Query parameters from pydantic model


Is there a way to convert a pydantic model to query parameters in fastapi?

Some of my endpoints pass parameters via the body, but some others pass them directly in the query. All this endpoints share the same data model, for example:

class Model(BaseModel):
    x: str
    y: str

I would like to avoid duplicating my definition of this model in the definition of my "query-parameters endpoints", like for example test_query in this code:

class Model(BaseModel):
    x: str
    y: str

@app.post("/test-body")
def test_body(model: Model): pass

@app.post("/test-query-params")
def test_query(x: str, y: str): pass

What's the cleanest way of doing this?


Solution

  • The documentation gives some examples in the shortcut section to avoid this kind of repetitions. In this case, it would give:

    from fastapi import Depends
    
    @app.post("/test-query-params")
    def test_query(model: Model = Depends()): pass
    

    This will allow you to request /test-query-params?x=1&y=2 and will also produce the correct OpenAPI description for this endpoint.

    If you use python ≥ 3.9, you can also make use of the typing.Annotated construct that more formally describes that Depends() is some typing metadata (validation/documentation generation/...):

    from typing import Annotated
    from fastapi import Depends
    
    @app.post("/test-query-params")
    def test_query(model: Annotated[Model, Depends()]): pass
    

    Similar solutions can be used for using Pydantic models as form-data descriptors.