Responses
Starlette includes a few response classes that handle sending back theappropriate ASGI messages on thesend channel.
Response
Signature:Response(content, status_code=200, headers=None, media_type=None)
content- A string or bytestring.status_code- An integer HTTP status code.headers- A dictionary of strings.media_type- A string giving the media type. eg. "text/html"
Starlette will automatically include a Content-Length header. It will alsoinclude a Content-Type header, based on the media_type and appending a charsetfor text types, unless a charset has already been specified in themedia_type.
Once you've instantiated a response, you can send it by calling it as anASGI application instance.
fromstarlette.responsesimportResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'response=Response('Hello, world!',media_type='text/plain')awaitresponse(scope,receive,send)Set Cookie
Starlette provides aset_cookie method to allow you to set cookies on the response object.
Signature:Response.set_cookie(key, value, max_age=None, expires=None, path="/", domain=None, secure=False, httponly=False, samesite="lax", partitioned=False)
key- A string that will be the cookie's key.value- A string that will be the cookie's value.max_age- An integer that defines the lifetime of the cookie in seconds. A negative integer or a value of0will discard the cookie immediately.Optionalexpires- Either an integer that defines the number of seconds until the cookie expires, or a datetime.Optionalpath- A string that specifies the subset of routes to which the cookie will apply.Optionaldomain- A string that specifies the domain for which the cookie is valid.Optionalsecure- A bool indicating that the cookie will only be sent to the server if request is made using SSL and the HTTPS protocol.Optionalhttponly- A bool indicating that the cookie cannot be accessed via JavaScript throughDocument.cookieproperty, theXMLHttpRequestorRequestAPIs.Optionalsamesite- A string that specifies the samesite strategy for the cookie. Valid values are'lax','strict'and'none'. Defaults to'lax'.Optionalpartitioned- A bool that indicates to user agents that these cross-site cookies should only be available in the same top-level context that the cookie was first set in. Only available for Python 3.14+, otherwise an error will be raised.Optional
Delete Cookie
Conversely, Starlette also provides adelete_cookie method to manually expire a set cookie.
Signature:Response.delete_cookie(key, path='/', domain=None)
HTMLResponse
Takes some text or bytes and returns an HTML response.
fromstarlette.responsesimportHTMLResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'response=HTMLResponse('<html><body><h1>Hello, world!</h1></body></html>')awaitresponse(scope,receive,send)PlainTextResponse
Takes some text or bytes and returns a plain text response.
fromstarlette.responsesimportPlainTextResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'response=PlainTextResponse('Hello, world!')awaitresponse(scope,receive,send)JSONResponse
Takes some data and returns anapplication/json encoded response.
fromstarlette.responsesimportJSONResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'response=JSONResponse({'hello':'world'})awaitresponse(scope,receive,send)Custom JSON serialization
If you need fine-grained control over JSON serialization, you can subclassJSONResponse and override therender method.
For example, if you wanted to use a third-party JSON library such asorjson:
fromtypingimportAnyimportorjsonfromstarlette.responsesimportJSONResponseclassOrjsonResponse(JSONResponse):defrender(self,content:Any)->bytes:returnorjson.dumps(content)In general youprobably want to stick withJSONResponse by default unlessyou are micro-optimising a particular endpoint or need to serialize non-standardobject types.
RedirectResponse
Returns an HTTP redirect. Uses a 307 status code by default.
fromstarlette.responsesimportPlainTextResponse,RedirectResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'ifscope['path']!='/':response=RedirectResponse(url='/')else:response=PlainTextResponse('Hello, world!')awaitresponse(scope,receive,send)StreamingResponse
Takes an async generator or a normal generator/iterator and streams the response body.
fromstarlette.responsesimportStreamingResponseimportasyncioasyncdefslow_numbers(minimum,maximum):yield'<html><body><ul>'fornumberinrange(minimum,maximum+1):yield'<li>%d</li>'%numberawaitasyncio.sleep(0.5)yield'</ul></body></html>'asyncdefapp(scope,receive,send):assertscope['type']=='http'generator=slow_numbers(1,10)response=StreamingResponse(generator,media_type='text/html')awaitresponse(scope,receive,send)Have in mind thatfile-like objects (like those created byopen()) are normal iterators. So, you can return them directly in aStreamingResponse.
FileResponse
Asynchronously streams a file as the response.
Takes a different set of arguments to instantiate than the other response types:
path- The filepath 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.content_disposition_type- will be included in the responseContent-Disposition. Can be set to "attachment" (default) or "inline".
File responses will include appropriateContent-Length,Last-Modified andETag headers.
fromstarlette.responsesimportFileResponseasyncdefapp(scope,receive,send):assertscope['type']=='http'response=FileResponse('statics/favicon.ico')awaitresponse(scope,receive,send)File responses also supportsHTTP range requests.
TheAccept-Ranges: bytes header will be included in the response if the file exists. For now, only thebytesrange unit is supported.
If the request includes aRange header, and the file exists, the response will be a206 Partial Content responsewith the requested range of bytes. If the range is invalid, the response will be a416 Range Not Satisfiable response.
Third party responses
EventSourceResponse
A response class that implementsServer-Sent Events. It enables event streaming from the server to the client without the complexity of websockets.