Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to declare a FastAPI response model using parameters

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "how to use parameters to declare the FastAPI response model". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

You can use the response_model parameter in any path operation to declare the model for the response:

@ app.get ()

@ app.post ()

@ app.put ()

@ app.delete ()

Wait.

From typing import List, Optional

From fastapi import FastAPI

From pydantic import BaseModel

App = FastAPI ()

Class Item (BaseModel):

Name: str

Description: Optional [str] = None

Price: float

Tax: Optional [float] = None

Tags: List [str] = []

@ app.post ("/ items/", response_model=Item)

Async def create_item (item: Item):

Return item

Note

Note that response_model is a parameter to the decorator method (get,post, etc.). Unlike all previous parameters and request bodies, it does not belong to the path operation function.

It receives the same type as you will declare for the Pydantic model property, so it can be a Pydantic model, but it can also be a list made up of Pydantic models, such as List [Item].

FastAPI will use this response_model to:

Converts the output data to its declared type.

Check the data.

Add a JSON Schema for the response in the path operation of the OpenAPI.

And used in the automatic document generation system.

But most importantly:

The output data is limited to the model definition. We'll see how important this is next.

Technical details

The response model is declared in the parameter, not as an annotation of the function return type, because the path function may not actually return the response model, but rather a dict, database object, or other model, and then use response_model to perform field constraints and serialization.

1. Return the same data as input

Now let's declare a UserIn model that will contain a plaintext password attribute.

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel, EmailStr

App = FastAPI ()

Class UserIn (BaseModel):

Username: str

Password: str

Email: EmailStr

Full_name: Optional [str] = None

# Don't do this in production!

@ app.post ("/ user/", response_model=UserIn)

Async def create_user (user: UserIn):

Return user

We are using this model to declare input data and the same model declaration to output data:

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel, EmailStr

App = FastAPI ()

Class UserIn (BaseModel):

Username: str

Password: str

Email: EmailStr

Full_name: Optional [str] = None

# Don't do this in production!

@ app.post ("/ user/", response_model=UserIn)

Async def create_user (user: UserIn):

Return user

Now, every time a browser creates a user with a password, API returns the same password in the response.

In this case, this may not be a problem because the user is sending the password himself.

However, if we use the same model in other path operations, we may send the user's password to each client.

Danger

Never store a user's plaintext password or send a password in a response.

3. Add output model

Instead, we can create an input model with a plaintext password and an output model without a plaintext password:

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel, EmailStr

App = FastAPI ()

Class UserIn (BaseModel):

Username: str

Password: str

Email: EmailStr

Full_name: Optional [str] = None

Class UserOut (BaseModel):

Username: str

Email: EmailStr

Full_name: Optional [str] = None

@ app.post ("/ user/", response_model=UserOut)

Async def create_user (user: UserIn):

Return user

In this way, even if our path operation function will return the same input user with the password:

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel, EmailStr

App = FastAPI ()

Class UserIn (BaseModel):

Username: str

Password: str

Email: EmailStr

Full_name: Optional [str] = None

Class UserOut (BaseModel):

Username: str

Email: EmailStr

Full_name: Optional [str] = None

@ app.post ("/ user/", response_model=UserOut)

Async def create_user (user: UserIn):

Return user

... We have declared response_model as a UserOut model that does not contain passwords:

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel, EmailStr

App = FastAPI ()

Class UserIn (BaseModel):

Username: str

Password: str

Email: EmailStr

Full_name: Optional [str] = None

Class UserOut (BaseModel):

Username: str

Email: EmailStr

Full_name: Optional [str] = None

@ app.post ("/ user/", response_model=UserOut)

Async def create_user (user: UserIn):

Return user

Therefore, FastAPI will be responsible for filtering out all data that is not declared in the output model (using Pydantic).

4. View in the document

When you view the automation document, you can check that both the input model and the output model have their own JSON Schema:

And both models will be used in interactive API documents:

5. Response model coding parameters

Your response model can have default values, such as:

From typing import List, Optional

From fastapi import FastAPI

From pydantic import BaseModel

App = FastAPI ()

Class Item (BaseModel):

Name: str

Description: Optional [str] = None

Price: float

Tax: float = 10.5

Tags: List [str] = []

Items = {

"foo": {"name": "Foo", "price": 50.2}

"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}

"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}

}

@ app.get ("/ items/ {item_id}", response_model=Item, response_model_exclude_unset=True)

Async def read_item (item_id: str):

Return items[item _ id]

Description: Optional [str] = None has a default value of None.

Tax: float = 10.5 has a default value of 10.5.

Tags: List [str] = [] has an empty list as the default: [].

But if they don't store the actual values, you may want to ignore their default values from the results.

For example, when you save a model with many optional attributes in a NoSQL database, but you don't want to send a long JSON response full of default values.

6. Use the response_model_exclude_unset parameter (excluding default and null values)

You can set the response_model_exclude_unset=True parameter of the path manipulation decorator:

From typing import List, Optional

From fastapi import FastAPI

From pydantic import BaseModel

App = FastAPI ()

Class Item (BaseModel):

Name: str

Description: Optional [str] = None

Price: float

Tax: float = 10.5

Tags: List [str] = []

Items = {

"foo": {"name": "Foo", "price": 50.2}

"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}

"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}

}

@ app.get ("/ items/ {item_id}", response_model=Item, response_model_exclude_unset=True)

Async def read_item (item_id: str):

Return items[item _ id]

Then those default values will not be included in the response, but only the values that are actually set.

Therefore, if you send a request for an item whose ID is foo to the path operation, the response (excluding the default) will be:

{

"name": "Foo"

"price": 50.2

}

Info

FastAPI does this through the .dict () of the Pydantic model in conjunction with the exclude_unset parameter of the method.

Info

You can also use:

Response_model_exclude_defaults=True

Response_model_exclude_none=True

Refer to the description of exclude_defaults and exclude_none in the Pydantic documentation.

7. Data with actual values in the default value field

However, if your data has an actual value in a model field with a default value, such as an item with an ID of bar:

{

"name": "Bar"

"description": "The bartenders"

"price": 62

"tax": 20.2

}

These values will be included in the response.

8. Data with the same value as the default value

If the data has the same value as the default value, for example, an item whose ID is baz:

{

"name": "Baz"

"description": None

"price": 50.2

Tax: 10.5

"tags": []

}

Even if description, tax, and tags have the same values as the default values, FastAPI is smart enough (and actually Pydantic is smart enough) to realize that their values are explicitly set (rather than taken from the default values).

Therefore, they will be included in the JSON response.

Tip

Note that the default value can be any value, not just None.

They can be a list ([]), a float with a value of 10.5, and so on.

9. Response_model_include and response_model_exclude

You can also use the path to manipulate the decorator's response_model_include and response_model_exclude parameters.

They receive a set consisting of the attribute name str to include (ignore others) or exclude (include others) these attributes.

You can use this shortcut if you have only one Pydantic model and want to remove some data from the output.

Tip

However, it is still recommended that you use the idea mentioned above and use multiple classes instead of these parameters. This is because even if you use response_model_include or response_model_exclude to omit some properties, the JSON Schema generated in the application's OpenAPI definition (and document) will still be a complete model.

This also applies to response_model_by_alias with similar effects.

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel

App = FastAPI ()

Class Item (BaseModel):

Name: str

Description: Optional [str] = None

Price: float

Tax: float = 10.5

Items = {

"foo": {"name": "Foo", "price": 50.2}

"bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2}

"baz": {

"name": "Baz"

"description": "There goes my baz"

"price": 50.2

Tax: 10.5

}

}

@ app.get (

"/ items/ {item_id} / name"

Response_model=Item

Response_model_include= {"name", "description"}

)

Async def read_item_name (item_id: str):

Return items [item _ id] Dalian abortion Hospital http://mobile.84211111.cn/

@ app.get ("/ items/ {item_id} / public", response_model=Item, response_model_exclude= {"tax"})

Async def read_item_public_data (item_id: str):

Return items[item _ id]

Tip

The {"name", "description"} syntax creates a set with these two values.

Equivalent to set (["name", "description"]).

10. Use list instead of set

If you forget to use set and instead use list or tuple,FastAPI, it will still be converted to set and work:

From typing import Optional

From fastapi import FastAPI

From pydantic import BaseModel

App = FastAPI ()

Class Item (BaseModel):

Name: str

Description: Optional [str] = None

Price: float

Tax: float = 10.5

Items = {

"foo": {"name": "Foo", "price": 50.2}

"bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2}

"baz": {

"name": "Baz"

"description": "There goes my baz"

"price": 50.2

Tax: 10.5

}

}

@ app.get (

"/ items/ {item_id} / name"

Response_model=Item

Response_model_include= ["name", "description"]

)

Async def read_item_name (item_id: str):

Return items[item _ id]

@ app.get ("/ items/ {item_id} / public", response_model=Item, response_model_exclude= ["tax"])

Async def read_item_public_data (item_id: str):

Return items[item _ id]

That's all for "how to declare a FastAPI response model using parameters". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report