starlette/docs/responses.md

246 lines
7.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Starlette includes a few response classes that handle sending back the
appropriate ASGI messages on the `send` 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 also
include a Content-Type header, based on the media_type and appending a charset
for text types.
Once you've instantiated a response, you can send it by calling it as an
ASGI application instance.
```python
from starlette.responses import Response
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = Response('Hello, world!', media_type='text/plain')
await response(receive, send)
```
#### Set Cookie
Starlette provides a `set_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)`
* `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 of `0` will discard the cookie immediately. `Optional`
* `expires` - An integer that defines the number of seconds until the cookie expires. `Optional`
* `path` - A string that specifies the subset of routes to which the cookie will apply. `Optional`
* `domain` - A string that specifies the domain for which the cookie is valid. `Optional`
* `secure` - A bool indicating that the cookie will only be sent to the server if request is made using SSL and the HTTPS protocol. `Optional`
* `httponly` - A bool indicating that the cookie cannot be accessed via Javascript through `Document.cookie` property, the `XMLHttpRequest` or `Request` APIs. `Optional`
#### Delete Cookie
Conversly, Starlette also provides a `delete_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.
```python
from starlette.responses import HTMLResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = HTMLResponse('<html><body><h1>Hello, world!</h1></body></html>')
await response(receive, send)
```
### PlainTextResponse
Takes some text or bytes and returns an plain text response.
```python
from starlette.responses import PlainTextResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = PlainTextResponse('Hello, world!')
await response(receive, send)
```
### TemplateResponse
The `TemplateResponse` class return plain text responses generated
from a template instance, and a dictionary of context to render into the
template.
A `request` argument must always be included in the context. Responses default
to `text/html` unless an alternative `media_type` is specified.
```python
from starlette.responses import TemplateResponse
from starlette.requests import Request
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
template = env.get_template('index.html')
context = {
'request': Request(self.scope),
}
response = TemplateResponse(template, context)
await response(receive, send)
```
The advantage with using `TemplateResponse` over `HTMLResponse` is that
it will make `template` and `context` properties available on response instances
returned by the test client.
```python
def test_app():
client = TestClient(App)
response = client.get("/")
assert response.status_code == 200
assert response.template.name == "index.html"
assert "request" in response.context
```
### JSONResponse
Takes some data and returns an `application/json` encoded response.
```python
from starlette.responses import JSONResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = JSONResponse({'hello': 'world'})
await response(receive, send)
```
### UJSONResponse
A JSON response class that uses the optimised `ujson` library for serialisation.
Using `ujson` will result in faster JSON serialisation, but is also less careful
than Python's built-in implementation in how it handles some edge-cases.
In general you *probably* want to stick with `JSONResponse` by default unless
you are micro-optimising a particular endpoint.
```python
from starlette.responses import UJSONResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = UJSONResponse({'hello': 'world'})
await response(receive, send)
```
### RedirectResponse
Returns an HTTP redirect. Uses a 302 status code by default.
```python
from starlette.responses import PlainTextResponse, RedirectResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
if self.scope['path'] != '/':
response = RedirectResponse(url='/')
else:
response = PlainTextResponse('Hello, world!')
await response(receive, send)
```
### StreamingResponse
Takes an async generator and streams the response body.
```python
from starlette.responses import StreamingResponse
import asyncio
async def slow_numbers(minimum, maximum):
yield('<html><body><ul>')
for number in range(minimum, maximum + 1):
yield '<li>%d</li>' % number
await asyncio.sleep(0.5)
yield('</ul></body></html>')
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
generator = slow_numbers(1, 10)
response = StreamingResponse(generator, media_type='text/html')
await response(receive, send)
```
### 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 response `Content-Disposition`.
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
```python
from starlette.responses import FileResponse
class App:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
response = FileResponse('statics/favicon.ico')
await response(receive, send)
```