Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 486
cglacet Avatar asked Jun 19 '20 10:06

cglacet


People also ask

What is query parameter in Mulesoft?

Query Parameter is basically used to filter or sort the resources. It is passed in the URL as query string in key-value form.

Which is an example of a query parameter?

Query Parameter Example For example, in `https://www.google.com/search?q=abstract%20api`, we have a standard Google search, with the user input `abstract%20api` being passed as a variable via the query parameter `q=`. We can pass multiple variables with the `&` symbol separating parameters, forming a query string.


3 Answers

The documentation gives a shortcut 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.

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

like image 111
cglacet Avatar answered Oct 23 '22 12:10

cglacet


This solution is very apt if your schema is "minimal".

But, when it comes to a complicated one like this, Set description for query parameter in swagger doc using Pydantic model, it is better to use a "custom dependency class"

from fastapi import Depends, FastAPI, Query

app = FastAPI()


class Model:
    def __init__(
            self,
            y: str,
            x: str = Query(
                default='default for X',
                title='Title for X',
                deprecated=True
            )

    ):
        self.x = x
        self.y = y


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

If you are using this method, you will have more control over the OpenAPI doc.

like image 24
JPG Avatar answered Oct 23 '22 11:10

JPG


Special case that isn't mentioned in the documentation for Query Parameters Lists, for example with:

/members/&member_ids=1&member_ids=2

The answer provided by @cglacet will unfortunately ignore the array for such a model:

class Model(BaseModel):
    member_ids: List[str]

You need to modify your model like so:

 class Model(BaseModel):
     member_ids: List[str] = Field(Query([]))

Answer from @fnep on GitHub here

like image 1
Anthony Nguyen Avatar answered Oct 23 '22 12:10

Anthony Nguyen