생성된 JSON 스키마에 추가될 Pydantic 모델을 위한 examples을 선언할 수 있습니다.
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
🤓 Other versions and variants
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
fromfastapiimportFastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=NoneclassConfig: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
🤓 Other versions and variants
fromtypingimportUnionfromfastapiimportFastAPIfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=NoneclassConfig: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 스키마 결과에 추가되고, API 문서에서 사용합니다.
Pydantic 모델과 같이 Field()를 사용할 때 추가적인 examples를 선언할 수 있습니다:
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
🤓 Other versions and variants
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
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
🤓 Other versions and variants
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
Prefer to use the Annotated version if possible.
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
Prefer to use the Annotated version if possible.
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
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
🤓 Other versions and variants
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
Prefer to use the Annotated version if possible.
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
Prefer to use the Annotated version if possible.
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 스키마의 일부가 될 것입니다.
그럼에도 불구하고, 지금 이 문서를 작성하는 시간에, 문서 UI를 보여주는 역할을 맡은 Swagger UI는 JSON 스키마 속 데이터를 위한 여러 예제의 표현을 지원하지 않습니다. 하지만 해결 방안을 밑에서 읽어보세요.
다음 예시 속에 OpenAPI-특화 examples를 FastAPI 안에서 매개변수 openapi_examples 매개변수와 함께 선언할 수 있습니다:
Path()
Query()
Header()
Cookie()
Body()
Form()
File()
dict의 키가 또 다른 dict인 각 예제와 값을 구별합니다.
각각의 특정 examples 속 dict 예제는 다음을 포함할 수 있습니다:
summary: 예제에 대한 짧은 설명문.
description: 마크다운 텍스트를 포함할 수 있는 긴 설명문.
value: 실제로 보여지는 예시, 예를 들면 dict.
externalValue: value의 대안이며 예제를 가르키는 URL. 비록 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(openapi_examples={"normal":{"summary":"A normal example","description":"A **normal** item works correctly.","value":{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},},"converted":{"summary":"An example with converted data","description":"FastAPI can convert price `strings` to actual `numbers` automatically","value":{"name":"Bar","price":"35.4",},},"invalid":{"summary":"Invalid data is rejected with an error","value":{"name":"Baz","price":"thirty five point four",},},},),],):results={"item_id":item_id,"item":item}returnresults
🤓 Other versions and variants
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(openapi_examples={"normal":{"summary":"A normal example","description":"A **normal** item works correctly.","value":{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},},"converted":{"summary":"An example with converted data","description":"FastAPI can convert price `strings` to actual `numbers` automatically","value":{"name":"Bar","price":"35.4",},},"invalid":{"summary":"Invalid data is rejected with an error","value":{"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(openapi_examples={"normal":{"summary":"A normal example","description":"A **normal** item works correctly.","value":{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},},"converted":{"summary":"An example with converted data","description":"FastAPI can convert price `strings` to actual `numbers` automatically","value":{"name":"Bar","price":"35.4",},},"invalid":{"summary":"Invalid data is rejected with an error","value":{"name":"Baz","price":"thirty five point four",},},},),],):results={"item_id":item_id,"item":item}returnresults
Tip
Prefer to use the Annotated version if possible.
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(openapi_examples={"normal":{"summary":"A normal example","description":"A **normal** item works correctly.","value":{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},},"converted":{"summary":"An example with converted data","description":"FastAPI can convert price `strings` to actual `numbers` automatically","value":{"name":"Bar","price":"35.4",},},"invalid":{"summary":"Invalid data is rejected with an error","value":{"name":"Baz","price":"thirty five point four",},},},),):results={"item_id":item_id,"item":item}returnresults
Tip
Prefer to use the Annotated version if possible.
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(openapi_examples={"normal":{"summary":"A normal example","description":"A **normal** item works correctly.","value":{"name":"Foo","description":"A very nice Item","price":35.4,"tax":3.2,},},"converted":{"summary":"An example with converted data","description":"FastAPI can convert price `strings` to actual `numbers` automatically","value":{"name":"Bar","price":"35.4",},},"invalid":{"summary":"Invalid data is rejected with an error","value":{"name":"Baz","price":"thirty five point four",},},},),):results={"item_id":item_id,"item":item}returnresults
examples를 Pydantic 모델 속에 추가할 때, schema_extra 혹은 Field(examples=["something"])를 사용하면 Pydantic 모델의 JSON 스키마에 해당 예시가 추가됩니다.
그리고 Pydantic 모델의 JSON 스키마는 API의 OpenAPI에 포함되고, 그 후 문서 UI 속에서 사용됩니다.
FastAPI 0.99.0 이전 버전에서 (0.99.0 이상 버전은 새로운 OpenAPI 3.1.0을 사용합니다), example 혹은 examples를 다른 유틸리티(Query(), Body() 등)와 함께 사용했을 때, 저러한 예시는 데이터를 설명하는 JSON 스키마에 추가되지 않으며 (심지어 OpenAPI의 자체 JSON 스키마에도 포함되지 않습니다), OpenAPI의 경로 작동 선언에 직접적으로 추가됩니다 (JSON 스키마를 사용하는 OpenAPI 부분 외에도).
하지만 지금은 FastAPI 0.99.0 및 이후 버전에서는 JSON 스키마 2020-12를 사용하는 OpenAPI 3.1.0과 Swagger UI 5.0.0 및 이후 버전을 사용하며, 모든 것이 더 일관성을 띄고 예시는 JSON 스키마에 포함됩니다.