Request

In order to manipulate the Request, you will need to include a parameter named request in your handler:

1
2
3
4
@app.route("/")
async def index(request):
    # do something with the request
    return ...

Common attributes

The Request object has many useful attributes, for example Request.method for the HTTP method used in the request, Request.headers for the HTTP headers included in the request, Request.path for the full path requested (without the domain name), Request.querystring for a dict of the querystrings included in the URL, Request.content_type for the request Content-Type.

Note

For a full list of attributes, see Request.

Request body

You can get the request body with Request.body() which will return a str of the full body, decoded with Request.encoding. If you want to work with a bytes body instead of a str body, you can use Request.raw_body() which will return a bytes instead of a str of the full body.

Note

Request.body() and Request.raw_body() are coroutines so you need to await them: await request.body()

Here’s an example on how to use these:

1
2
3
4
5
6
7
@app.route("/<path:path(allow_empty=True)>")
async def index(request):
    info = (
        "{0.method} {0.path} HTTP/{0.http_version} {0.content_type}"
        "Headers:\n{0.headers}\n\n{1}"
    ).format(request, await request.body())
    return info

This handler will be called for every path and will return information about the request: the method, the path, the HTTP version, the content type, the headers and the body.

JSON body

If you want to get the body decoded to JSON, you can use Request.json(). It will raise a BadRequest if the request body can’t be decoded as JSON, you can usually not handle this error as it will be handled by the app and converted to a response with a 400 status code.

Here’s an example for a user creation endpoint, it gets the username and email from the JSON body:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@app.route("/users", methods=["POST"])
async def user_create(request):
    user = await request.json()

    if not isinstance(user, dict):
        raise BadRequest(description="JSON body must be a dictionnary")

    try:
        username, email = user["username"], user["email"]
    except KeyError:
        raise BadRequest(description="JSON body must include username and email")

    # add the user to database
    ...

    return {"username": username, "email": email}

Form body

If you want to use forms, the easiest way to parse them from the request body is with Request.form() which will give you a Form. It will raise a ValueError if the Request.content_type isn’t one of application/x-www-form-urlencoded or multipart/form-data. You can also include the querystring arguments as form fields if some of your data is in the querystring.

The easiest way to use forms is with View:

From examples/forms.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FORM_HTML = """
<form action="/" method="POST">
<div>
    <label for="say">What greeting do you want to say?</label>
    <input name="say" id="say" value="Hi">
</div>
<div>
    <label for="to">Who do you want to say it to?</label>
    <input name="to" id="to" value="Mom">
</div>
<div>
    <button>Send my greetings</button>
</div>
</form>
"""

@app.route("/")
class Form(View):
    async def get(self):
        return FORM_HTML

    async def post(self, request):
        form = await request.form()
        return '<h1>Said "{}" to {}</h1>'.format(form["say"], form["to"])