Wenn Sie mit FastAPI beginnen, benötigen Sie dies möglicherweise nicht.
Sie können zusätzliche Responses mit zusätzlichen Statuscodes, Medientypen, Beschreibungen, usw. deklarieren.
Diese zusätzlichen Responses werden in das OpenAPI-Schema aufgenommen, sodass sie auch in der API-Dokumentation erscheinen.
Für diese zusätzlichen Responses müssen Sie jedoch sicherstellen, dass Sie eine Response, wie etwa JSONResponse, direkt zurückgeben, mit Ihrem Statuscode und Inhalt.
Sie können Ihren Pfadoperation-Dekoratoren einen Parameter responses übergeben.
Der nimmt ein dict entgegen, die Schlüssel sind Statuscodes für jede Response, wie etwa 200, und die Werte sind andere dicts mit den Informationen für jede Response.
Jedes dieser Response-dicts kann einen Schlüssel model haben, welcher ein Pydantic-Modell enthält, genau wie response_model.
FastAPI nimmt dieses Modell, generiert dessen JSON-Schema und fügt es an der richtigen Stelle in OpenAPI ein.
Um beispielsweise eine weitere Response mit dem Statuscode 404 und einem Pydantic-Modell Message zu deklarieren, können Sie schreiben:
fromfastapiimportFastAPIfromfastapi.responsesimportJSONResponsefrompydanticimportBaseModelclassItem(BaseModel):id:strvalue:strclassMessage(BaseModel):message:strapp=FastAPI()@app.get("/items/{item_id}",response_model=Item,responses={404:{"model":Message}})asyncdefread_item(item_id:str):ifitem_id=="foo":return{"id":"foo","value":"there goes my hero"}returnJSONResponse(status_code=404,content={"message":"Item not found"})
Hinweis
Beachten Sie, dass Sie die JSONResponse direkt zurückgeben müssen.
Info
Der model-Schlüssel ist nicht Teil von OpenAPI.
FastAPI nimmt das Pydantic-Modell von dort, generiert das JSON-Schema und fügt es an der richtigen Stelle ein.
Die richtige Stelle ist:
Im Schlüssel content, der als Wert ein weiteres JSON-Objekt (dict) hat, welches Folgendes enthält:
Ein Schlüssel mit dem Medientyp, z. B. application/json, der als Wert ein weiteres JSON-Objekt hat, welches Folgendes enthält:
Ein Schlüssel schema, der als Wert das JSON-Schema aus dem Modell hat, hier ist die richtige Stelle.
FastAPI fügt hier eine Referenz auf die globalen JSON-Schemas an einer anderen Stelle in Ihrer OpenAPI hinzu, anstatt es direkt einzubinden. Auf diese Weise können andere Anwendungen und Clients diese JSON-Schemas direkt verwenden, bessere Tools zur Codegenerierung bereitstellen, usw.
Die generierten Responses in der OpenAPI für diese Pfadoperation lauten:
Sie können denselben responses-Parameter verwenden, um verschiedene Medientypen für dieselbe Haupt-Response hinzuzufügen.
Sie können beispielsweise einen zusätzlichen Medientyp image/png hinzufügen und damit deklarieren, dass Ihre Pfadoperation ein JSON-Objekt (mit dem Medientyp application/json) oder ein PNG-Bild zurückgeben kann:
fromtypingimportUnionfromfastapiimportFastAPIfromfastapi.responsesimportFileResponsefrompydanticimportBaseModelclassItem(BaseModel):id:strvalue:strapp=FastAPI()@app.get("/items/{item_id}",response_model=Item,responses={200:{"content":{"image/png":{}},"description":"Return the JSON item or an image.",}},)asyncdefread_item(item_id:str,img:Union[bool,None]=None):ifimg:returnFileResponse("image.png",media_type="image/png")else:return{"id":"foo","value":"there goes my hero"}
Hinweis
Beachten Sie, dass Sie das Bild direkt mit einer FileResponse zurückgeben müssen.
Info
Sofern Sie in Ihrem Parameter responses nicht explizit einen anderen Medientyp angeben, geht FastAPI davon aus, dass die Response denselben Medientyp wie die Haupt-Response-Klasse hat (Standardmäßig application/json).
Wenn Sie jedoch eine benutzerdefinierte Response-Klasse mit None als Medientyp angegeben haben, verwendet FastAPI application/json für jede zusätzliche Response, die über ein zugehöriges Modell verfügt.
Sie können auch Response-Informationen von mehreren Stellen kombinieren, einschließlich der Parameter response_model, status_code und responses.
Sie können ein response_model deklarieren, indem Sie den Standardstatuscode 200 (oder bei Bedarf einen benutzerdefinierten) verwenden und dann zusätzliche Informationen für dieselbe Response in responses direkt im OpenAPI-Schema deklarieren.
FastAPI behält die zusätzlichen Informationen aus responses und kombiniert sie mit dem JSON-Schema aus Ihrem Modell.
Sie können beispielsweise eine Response mit dem Statuscode 404 deklarieren, die ein Pydantic-Modell verwendet und über eine benutzerdefinierte Beschreibung (description) verfügt.
Und eine Response mit dem Statuscode 200, die Ihr response_model verwendet, aber ein benutzerdefiniertes Beispiel (example) enthält:
fromfastapiimportFastAPIfromfastapi.responsesimportJSONResponsefrompydanticimportBaseModelclassItem(BaseModel):id:strvalue:strclassMessage(BaseModel):message:strapp=FastAPI()@app.get("/items/{item_id}",response_model=Item,responses={404:{"model":Message,"description":"The item was not found"},200:{"description":"Item requested by ID","content":{"application/json":{"example":{"id":"bar","value":"The bar tenders"}}},},},)asyncdefread_item(item_id:str):ifitem_id=="foo":return{"id":"foo","value":"there goes my hero"}else:returnJSONResponse(status_code=404,content={"message":"Item not found"})
Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:
Vordefinierte und benutzerdefinierte Responses kombinieren¶
Möglicherweise möchten Sie einige vordefinierte Responses haben, die für viele Pfadoperationen gelten, Sie möchten diese jedoch mit benutzerdefinierten Responses kombinieren, die für jede Pfadoperation erforderlich sind.
In diesen Fällen können Sie die Python-Technik zum „Entpacken“ eines dicts mit **dict_to_unpack verwenden:
old_dict={"old key":"old value","second old key":"second old value",}new_dict={**old_dict,"new key":"new value"}
Hier wird new_dict alle Schlüssel-Wert-Paare von old_dict plus das neue Schlüssel-Wert-Paar enthalten:
{"old key":"old value","second old key":"second old value","new key":"new value",}
Mit dieser Technik können Sie einige vordefinierte Responses in Ihren Pfadoperationen wiederverwenden und sie mit zusätzlichen benutzerdefinierten Responses kombinieren.
Zum Beispiel:
fromtypingimportUnionfromfastapiimportFastAPIfromfastapi.responsesimportFileResponsefrompydanticimportBaseModelclassItem(BaseModel):id:strvalue:strresponses={404:{"description":"Item not found"},302:{"description":"The item was moved"},403:{"description":"Not enough privileges"},}app=FastAPI()@app.get("/items/{item_id}",response_model=Item,responses={**responses,200:{"content":{"image/png":{}}}},)asyncdefread_item(item_id:str,img:Union[bool,None]=None):ifimg:returnFileResponse("image.png",media_type="image/png")else:return{"id":"foo","value":"there goes my hero"}
OpenAPI Response Object, Sie können alles davon direkt in jede Response innerhalb Ihres responses-Parameter einfügen. Einschließlich description, headers, content (darin deklarieren Sie verschiedene Medientypen und JSON-Schemas) und links.