Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Join theFastAPI Cloud waiting list 🚀
Follow@fastapi onX (Twitter) to stay updated
FollowFastAPI onLinkedIn to stay updated
Subscribe to theFastAPI and friends newsletter 🎉
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor

Custom Response - HTML, Stream, File, others

By default,FastAPI will return the responses usingJSONResponse.

You can override it by returning aResponse directly as seen inReturn a Response directly.

But if you return aResponse directly (or any subclass, likeJSONResponse), the data won't be automatically converted (even if you declare aresponse_model), and the documentation won't be automatically generated (for example, including the specific "media type", in the HTTP headerContent-Type as part of the generated OpenAPI).

But you can also declare theResponse that you want to be used (e.g. anyResponse subclass), in thepath operation decorator using theresponse_class parameter.

The contents that you return from yourpath operation function will be put inside of thatResponse.

And if thatResponse has a JSON media type (application/json), like is the case with theJSONResponse andUJSONResponse, the data you return will be automatically converted (and filtered) with any Pydanticresponse_model that you declared in thepath operation decorator.

Note

If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.

UseORJSONResponse

For example, if you are squeezing performance, you can install and useorjson and set the response to beORJSONResponse.

Import theResponse class (sub-class) you want to use and declare it in thepath operation decorator.

For large responses, returning aResponse directly is much faster than returning a dictionary.

This is because by default, FastAPI will inspect every item inside and make sure it is serializable as JSON, using the sameJSON Compatible Encoder explained in the tutorial. This is what allows you to returnarbitrary objects, for example database models.

But if you are certain that the content that you are returning isserializable with JSON, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through thejsonable_encoder before passing it to the response class.

fromfastapiimportFastAPIfromfastapi.responsesimportORJSONResponseapp=FastAPI()@app.get("/items/",response_class=ORJSONResponse)asyncdefread_items():returnORJSONResponse([{"item_id":"Foo"}])

Info

The parameterresponse_class will also be used to define the "media type" of the response.

In this case, the HTTP headerContent-Type will be set toapplication/json.

And it will be documented as such in OpenAPI.

Tip

TheORJSONResponse is only available in FastAPI, not in Starlette.

HTML Response

To return a response with HTML directly fromFastAPI, useHTMLResponse.

  • ImportHTMLResponse.
  • PassHTMLResponse as the parameterresponse_class of yourpath operation decorator.
fromfastapiimportFastAPIfromfastapi.responsesimportHTMLResponseapp=FastAPI()@app.get("/items/",response_class=HTMLResponse)asyncdefread_items():return"""    <html>        <head>            <title>Some HTML in here</title>        </head>        <body>            <h1>Look ma! HTML!</h1>        </body>    </html>    """

Info

The parameterresponse_class will also be used to define the "media type" of the response.

In this case, the HTTP headerContent-Type will be set totext/html.

And it will be documented as such in OpenAPI.

Return aResponse

As seen inReturn a Response directly, you can also override the response directly in yourpath operation, by returning it.

The same example from above, returning anHTMLResponse, could look like:

fromfastapiimportFastAPIfromfastapi.responsesimportHTMLResponseapp=FastAPI()@app.get("/items/")asyncdefread_items():html_content="""    <html>        <head>            <title>Some HTML in here</title>        </head>        <body>            <h1>Look ma! HTML!</h1>        </body>    </html>    """returnHTMLResponse(content=html_content,status_code=200)

Warning

AResponse returned directly by yourpath operation function won't be documented in OpenAPI (for example, theContent-Type won't be documented) and won't be visible in the automatic interactive docs.

Info

Of course, the actualContent-Type header, status code, etc, will come from theResponse object you returned.

Document in OpenAPI and overrideResponse

If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use theresponse_class parameter AND return aResponse object.

Theresponse_class will then be used only to document the OpenAPIpath operation, but yourResponse will be used as is.

Return anHTMLResponse directly

For example, it could be something like:

fromfastapiimportFastAPIfromfastapi.responsesimportHTMLResponseapp=FastAPI()defgenerate_html_response():html_content="""    <html>        <head>            <title>Some HTML in here</title>        </head>        <body>            <h1>Look ma! HTML!</h1>        </body>    </html>    """returnHTMLResponse(content=html_content,status_code=200)@app.get("/items/",response_class=HTMLResponse)asyncdefread_items():returngenerate_html_response()

In this example, the functiongenerate_html_response() already generates and returns aResponse instead of returning the HTML in astr.

By returning the result of callinggenerate_html_response(), you are already returning aResponse that will override the defaultFastAPI behavior.

But as you passed theHTMLResponse in theresponse_class too,FastAPI will know how to document it in OpenAPI and the interactive docs as HTML withtext/html:

Available responses

Here are some of the available responses.

Keep in mind that you can useResponse to return anything else, or even create a custom sub-class.

Technical Details

You could also usefrom starlette.responses import HTMLResponse.

FastAPI provides the samestarlette.responses asfastapi.responses just as a convenience for you, the developer. But most of the available responses come directly from Starlette.

Response

The mainResponse class, all the other responses inherit from it.

You can return it directly.

It accepts the following parameters:

  • content - Astr orbytes.
  • status_code - Anint HTTP status code.
  • headers - Adict of strings.
  • media_type - Astr giving the media type. E.g."text/html".

FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on themedia_type and appending a charset for text types.

fromfastapiimportFastAPI,Responseapp=FastAPI()@app.get("/legacy/")defget_legacy_data():data="""<?xml version="1.0"?>    <shampoo>    <Header>        Apply shampoo here.    </Header>    <Body>        You'll have to use soap here.    </Body>    </shampoo>    """returnResponse(content=data,media_type="application/xml")

HTMLResponse

Takes some text or bytes and returns an HTML response, as you read above.

PlainTextResponse

Takes some text or bytes and returns a plain text response.

fromfastapiimportFastAPIfromfastapi.responsesimportPlainTextResponseapp=FastAPI()@app.get("/",response_class=PlainTextResponse)asyncdefmain():return"Hello World"

JSONResponse

Takes some data and returns anapplication/json encoded response.

This is the default response used inFastAPI, as you read above.

ORJSONResponse

A fast alternative JSON response usingorjson, as you read above.

Info

This requires installingorjson for example withpip install orjson.

UJSONResponse

An alternative JSON response usingujson.

Info

This requires installingujson for example withpip install ujson.

Warning

ujson is less careful than Python's built-in implementation in how it handles some edge-cases.

fromfastapiimportFastAPIfromfastapi.responsesimportUJSONResponseapp=FastAPI()@app.get("/items/",response_class=UJSONResponse)asyncdefread_items():return[{"item_id":"Foo"}]

Tip

It's possible thatORJSONResponse might be a faster alternative.

RedirectResponse

Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.

You can return aRedirectResponse directly:

fromfastapiimportFastAPIfromfastapi.responsesimportRedirectResponseapp=FastAPI()@app.get("/typer")asyncdefredirect_typer():returnRedirectResponse("https://typer.tiangolo.com")

Or you can use it in theresponse_class parameter:

fromfastapiimportFastAPIfromfastapi.responsesimportRedirectResponseapp=FastAPI()@app.get("/fastapi",response_class=RedirectResponse)asyncdefredirect_fastapi():return"https://fastapi.tiangolo.com"

If you do that, then you can return the URL directly from yourpath operation function.

In this case, thestatus_code used will be the default one for theRedirectResponse, which is307.


You can also use thestatus_code parameter combined with theresponse_class parameter:

fromfastapiimportFastAPIfromfastapi.responsesimportRedirectResponseapp=FastAPI()@app.get("/pydantic",response_class=RedirectResponse,status_code=302)asyncdefredirect_pydantic():return"https://docs.pydantic.dev/"

StreamingResponse

Takes an async generator or a normal generator/iterator and streams the response body.

fromfastapiimportFastAPIfromfastapi.responsesimportStreamingResponseapp=FastAPI()asyncdeffake_video_streamer():foriinrange(10):yieldb"some fake video bytes"@app.get("/")asyncdefmain():returnStreamingResponse(fake_video_streamer())

UsingStreamingResponse with file-like objects

If you have afile-like object (e.g. the object returned byopen()), you can create a generator function to iterate over that file-like object.

That way, you don't have to read it all first in memory, and you can pass that generator function to theStreamingResponse, and return it.

This includes many libraries to interact with cloud storage, video processing, and others.

fromfastapiimportFastAPIfromfastapi.responsesimportStreamingResponsesome_file_path="large-video-file.mp4"app=FastAPI()@app.get("/")defmain():defiterfile():# (1)withopen(some_file_path,mode="rb")asfile_like:# (2)yield fromfile_like# (3)returnStreamingResponse(iterfile(),media_type="video/mp4")
  1. This is the generator function. It's a "generator function" because it containsyield statements inside.
  2. By using awith block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
  3. Thisyield from tells the function to iterate over that thing namedfile_like. And then, for each part iterated, yield that part as coming from this generator function (iterfile).

    So, it is a generator function that transfers the "generating" work to something else internally.

    By doing it this way, we can put it in awith block, and that way, ensure that the file-like object is closed after finishing.

Tip

Notice that here as we are using standardopen() that doesn't supportasync andawait, we declare the path operation with normaldef.

FileResponse

Asynchronously streams a file as the response.

Takes a different set of arguments to instantiate than the other response types:

  • path - The file path to the file to stream.
  • headers - Any custom headers to include, as a dictionary.
  • media_type - A string giving the media type. If unset, the filename or path will be used to infer a media type.
  • filename - If set, this will be included in the responseContent-Disposition.

File responses will include appropriateContent-Length,Last-Modified andETag headers.

fromfastapiimportFastAPIfromfastapi.responsesimportFileResponsesome_file_path="large-video-file.mp4"app=FastAPI()@app.get("/")asyncdefmain():returnFileResponse(some_file_path)

You can also use theresponse_class parameter:

fromfastapiimportFastAPIfromfastapi.responsesimportFileResponsesome_file_path="large-video-file.mp4"app=FastAPI()@app.get("/",response_class=FileResponse)asyncdefmain():returnsome_file_path

In this case, you can return the file path directly from yourpath operation function.

Custom response class

You can create your own custom response class, inheriting fromResponse and using it.

For example, let's say that you want to useorjson, but with some custom settings not used in the includedORJSONResponse class.

Let's say you want it to return indented and formatted JSON, so you want to use the orjson optionorjson.OPT_INDENT_2.

You could create aCustomORJSONResponse. The main thing you have to do is create aResponse.render(content) method that returns the content asbytes:

fromtypingimportAnyimportorjsonfromfastapiimportFastAPI,Responseapp=FastAPI()classCustomORJSONResponse(Response):media_type="application/json"defrender(self,content:Any)->bytes:assertorjsonisnotNone,"orjson must be installed"returnorjson.dumps(content,option=orjson.OPT_INDENT_2)@app.get("/",response_class=CustomORJSONResponse)asyncdefmain():return{"message":"Hello World"}

Now instead of returning:

{"message":"Hello World"}

...this response will return:

{"message":"Hello World"}

Of course, you will probably find much better ways to take advantage of this than formatting JSON. 😉

Default response class

When creating aFastAPI class instance or anAPIRouter you can specify which response class to use by default.

The parameter that defines this isdefault_response_class.

In the example below,FastAPI will useORJSONResponse by default, in allpath operations, instead ofJSONResponse.

fromfastapiimportFastAPIfromfastapi.responsesimportORJSONResponseapp=FastAPI(default_response_class=ORJSONResponse)@app.get("/items/")asyncdefread_items():return[{"item_id":"Foo"}]

Tip

You can still overrideresponse_class inpath operations as before.

Additional documentation

You can also declare the media type and many other details in OpenAPI usingresponses:Additional Responses in OpenAPI.


[8]ページ先頭

©2009-2026 Movatter.jp