Using the response_model parameter, the response model can be declared in the following path parameters:
- @app.get()
- @app.put()
- @app.post()
- @app.delete()
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: response_model is a parameter of the decorator method. Unlike the previous parameters and request body, it is not a parameter of the path operation function.
The type received by response_model is the same as the type that declares the Pydantic model property, which can be a Pydantic model or a list of Pydantic models, for example: List[Item]
returns the same input data
from typing import Optional from fastapi import FastAPI from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmilStr full_name: Optional[str] = None @app.post("/user/", response_model=UserIn) async def create_user(user: UserIn): return user
Use this model to declare input objects, and use the same model to declare output objects:
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, whenever a user is created with a password in the browser, the API will return the same password in the response china. In this example, since the user himself sends the password, this operation is fine, but if the same model is used in other path operations, the user's password will be sent to each client.
Add output model
Create an output model without a plaintext password relative to an input model with 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
Thus, even if the path manipulation function returns the same input user:
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
But because the UserOut model declared in response_model does not contain 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
FastAPI filters out all data not declared in the output model.
Response model encoding parameters
The response model supports default values:
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 The default value is None
- tax: float = 10.5 The default value is 10.5
- The default value of tags: List[str] = [] is an empty list: []
However, if no new value is assigned to a property with a default value, the output will omit the property with a default value.
For example, the model of a NoSQL database often contains many optional attributes. If the attribute with default value is output, the output JSON response will be very long. In this case, the attribute with only default value can be omitted.