Вы можете объявить ключ example для модели Pydantic, используя класс Config и переменную schema_extra, как описано в Pydantic документации: Настройка схемы:
fromfastapiimportFastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=Nonemodel_config={"json_schema_extra":{"examples":[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}]}}@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item):results={"item_id":item_id,"item":item}returnresults
fromtypingimportUnionfromfastapiimportFastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=Nonemodel_config={"json_schema_extra":{"examples":[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}]}}@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item):results={"item_id":item_id,"item":item}returnresults
Эта дополнительная информация будет включена в JSON Schema выходных данных для этой модели, и она будет использоваться в документации к API.
Tip
Вы можете использовать тот же метод для расширения JSON-схемы и добавления своей собственной дополнительной информации.
Например, вы можете использовать это для добавления дополнительной информации для пользовательского интерфейса в вашем веб-приложении и т.д.
При использовании Field() с моделями Pydantic, вы также можете объявлять дополнительную информацию для JSON Schema, передавая любые другие произвольные аргументы в функцию.
Вы можете использовать это, чтобы добавить аргумент example для каждого поля:
fromfastapiimportFastAPIfrompydanticimportBaseModel,Fieldapp=FastAPI()classItem(BaseModel):name:str=Field(examples=["Foo"])description:str|None=Field(default=None,examples=["A very nice Item"])price:float=Field(examples=[35.4])tax:float|None=Field(default=None,examples=[3.2])@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item):results={"item_id":item_id,"item":item}returnresults
fromtypingimportUnionfromfastapiimportFastAPIfrompydanticimportBaseModel,Fieldapp=FastAPI()classItem(BaseModel):name:str=Field(examples=["Foo"])description:Union[str,None]=Field(default=None,examples=["A very nice Item"])price:float=Field(examples=[35.4])tax:Union[float,None]=Field(default=None,examples=[3.2])@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item):results={"item_id":item_id,"item":item}returnresults
Warning
Имейте в виду, что эти дополнительные переданные аргументы не добавляют никакой валидации, только дополнительную информацию для документации.
Здесь мы передаём аргумент example, как пример данных ожидаемых в параметре Body():
fromtypingimportAnnotatedfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}],),],):results={"item_id":item_id,"item":item}returnresults
fromtypingimportAnnotated,UnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}],),],):results={"item_id":item_id,"item":item}returnresults
fromtypingimportUnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelfromtyping_extensionsimportAnnotatedapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}],),],):results={"item_id":item_id,"item":item}returnresults
Tip
Рекомендуется использовать версию с Annotated, если это возможно.
fromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item=Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}],),):results={"item_id":item_id,"item":item}returnresults
Tip
Рекомендуется использовать версию с Annotated, если это возможно.
fromtypingimportUnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int,item:Item=Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,}],),):results={"item_id":item_id,"item":item}returnresults
В качестве альтернативы одному аргументу example, вы можете передавать examples используя тип данных dict с несколькими примерами, каждый из которых содержит дополнительную информацию, которая также будет добавлена в OpenAPI.
Ключи dict указывают на каждый пример, а значения для каждого из них - на еще один тип dict с дополнительной информацией.
Каждый конкретный пример типа dict в аргументе examples может содержать:
summary: Краткое описание для примера.
description: Полное описание, которое может содержать текст в формате Markdown.
value: Это конкретный пример, который отображается, например, в виде типа dict.
externalValue: альтернатива параметру value, URL-адрес, указывающий на пример. Хотя это может не поддерживаться таким же количеством инструментов разработки и тестирования API, как параметр value.
fromtypingimportAnnotatedfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},{"name":"Bar","price":"35.4",},{"name":"Baz","price":"thirty five point four",},],),],):results={"item_id":item_id,"item":item}returnresults
fromtypingimportAnnotated,UnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},{"name":"Bar","price":"35.4",},{"name":"Baz","price":"thirty five point four",},],),],):results={"item_id":item_id,"item":item}returnresults
fromtypingimportUnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelfromtyping_extensionsimportAnnotatedapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int,item:Annotated[Item,Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},{"name":"Bar","price":"35.4",},{"name":"Baz","price":"thirty five point four",},],),],):results={"item_id":item_id,"item":item}returnresults
Tip
Рекомендуется использовать версию с Annotated, если это возможно.
fromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int,item:Item=Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},{"name":"Bar","price":"35.4",},{"name":"Baz","price":"thirty five point four",},],),):results={"item_id":item_id,"item":item}returnresults
Tip
Рекомендуется использовать версию с Annotated, если это возможно.
fromtypingimportUnionfromfastapiimportBody,FastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int,item:Item=Body(examples=[{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},{"name":"Bar","price":"35.4",},{"name":"Baz","price":"thirty five point four",},],),):results={"item_id":item_id,"item":item}returnresults
Эти технические детали относятся к стандартам JSON Schema и OpenAPI.
Если предложенные выше идеи уже работают для вас, возможно этого будет достаточно и эти детали вам не потребуются, можете спокойно их пропустить.
Когда вы добавляете пример внутрь модели Pydantic, используя schema_extra или Field(example="something"), этот пример добавляется в JSON Schema для данной модели Pydantic.
И эта JSON Schema модели Pydantic включается в OpenAPI вашего API, а затем используется в UI документации.
Поля example как такового не существует в стандартах JSON Schema. В последних версиях JSON-схемы определено поле examples, но OpenAPI 3.0.3 основан на более старой версии JSON-схемы, которая не имела поля examples.
Таким образом, OpenAPI 3.0.3 определяет своё собственное поле example для модифицированной версии JSON Schema, которую он использует чтобы достичь той же цели (однако это именно поле example, а не examples), и именно это используется API в UI документации (с интеграцией Swagger UI).
Итак, хотя поле example не является частью JSON-схемы, оно является частью настраиваемой версии JSON-схемы в OpenAPI, и именно это поле будет использоваться в UI документации.
Однако, когда вы используете поле example или examples с любой другой функцией (Query(), Body(), и т.д.), эти примеры не добавляются в JSON-схему, которая описывает эти данные (даже в собственную версию JSON-схемы OpenAPI), они добавляются непосредственно в объявление операции пути в OpenAPI (вне частей OpenAPI, которые используют JSON-схему).
С другой стороны, существует более новая версия OpenAPI: 3.1.0, недавно выпущенная. Она основана на последней версии JSON-схемы и большинство модификаций из OpenAPI JSON-схемы удалены в обмен на новые возможности из последней версии JSON-схемы, так что все эти мелкие отличия устранены. Тем не менее, Swagger UI в настоящее время не поддерживает OpenAPI 3.1.0, поэтому пока лучше продолжать использовать вышеупомянутые методы.