Skip to content

Request

Dawid Kraczkowski edited this page Feb 21, 2021 · 21 revisions

For each http request an application receives an instance of chocs.HttpRequest is created. A chocs.HttpRequest stores everything about HTTP request and provides handy interface to ease work with HTTP protocol.

chocs.HttpRequest class also provides an abstraction around WSGI's, AWS and in future other environments in which chocs may be running.

Reading request's body

Accessing request's contents is similar to reading a file. When chocs.HttpRequest.body is accessed it returns a copy of io.BytesIO instance stored within the request object.

import chocs

app = chocs.Application()

@app.post("/example")
def handle_request(request:chocs.HttpRequest) -> chocs.HttpResponse:
    contents = request.body.read()
    
    return chocs.HttpResponse(contents)

chocs.serve(app)

Accessing request's parsed body

To simplify daily tasks when working with requests containing specific data, chocs.HttpRequest provides additional attribute - parsed_body.

Depending on the HTTP request's content type header parsed body might be an instance of one of the following classes:

  • chocs.FormHttpMessage for requests containing form data which content type header is set to application/x-www-form-urlencoded
  • chocs.MultipartHttpMessage for requests containing files and form data which content type header is set to multipart/form-data
  • chocs.JsonHttpMessage for requests with json data which content type header is set to application/json
  • chocs.YamlHttpMessage for request with yaml data which content type header is set to text/yaml, text/x-yaml, application/x-yaml

All of the above objects provide simple dict like interface to access its contents.

Working with http forms

Having the following http form:

<form method="POST" action="/hello">
  <input type="text" name="first_name" value="John"><br>
  <input type="text" name="last_name" value="Doe"><br><br>
  <input type="submit" value="Submit">
</form> 

You can easily read the data with the following code snippet.

import chocs

app = chocs.Application()

@app.post("/hello")
def handle_request(request:chocs.HttpRequest) -> chocs.HttpResponse:
    body = request.parsed_body
    
    return chocs.HttpResponse(f"Hello {body['first_name']} {body['last_name']}")

chocs.serve(app)

Working with json/yaml requests

Having the following curl request:

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"first_name":"John","last_name":"Doe"}' \
  http://localhost/hello

The following is example how to handle it:

import chocs

app = chocs.Application()

@app.post("/hello")
def handle_request(request:chocs.HttpRequest) -> chocs.HttpResponse:
    body = request.parsed_body
    
    return chocs.HttpResponse(f"Hello {body['first_name']} {body['last_name']}")

chocs.serve(app)

Note: Same example can be used for handling yaml requests.

Accessing request's headers

HTTP Request headers can be accessed through chocs.HttpRequest.headers property which returns dict like chocs.HttpHeaders object.

import chocs

app = chocs.Application()

@app.get("/example")
def handle_request(request:chocs.HttpRequest) -> chocs.HttpResponse:
    content_type = request.headers.get("content-type", "text/plain")

    return chocs.HttpResponse(f"Your Content-Type header is: {content_type}")

chocs.serve(app)

Accessing path's parameters

When your application defined parametrised routes, you can access their values through chocs.HttpRequest.path_parameters attribute like in the example below:

import chocs

app = chocs.Application()

@app.get("/user/{user_id}")
def handle_request(request:chocs.HttpRequest) -> chocs.HttpResponse:
    user_id = request.path_parameters["user_id"]

    return chocs.HttpResponse(f"Your user id is: {user_id}")

chocs.serve(app)

Reading client cookies

Cookies can be easily accessed by chocs.HttpRequest.cookies attribute, which contains dict-like object. The following example shows how client's cookies can be accessed by your application.

import chocs

http = chocs.Application()


@http.get("/cookies")
def read_cookies(request: chocs.HttpRequest) -> chocs.HttpResponse:

    message = "Hello"
    if "user_name" in request.cookies:
        message += f", {str(request.cookies['user_name'])}"
    message += "!"

    return chocs.HttpResponse(body=message)

chocs.serve(http)

Comparing requests objects

Framework also provides interface to compare if two different instances of chocs.HttpRequest are equal. This scenario may be useful while running test suits.

Two instances of request are equal if:

  • their methods are the same
  • their headers are the same
  • their paths are the same
  • their query strings are the same
  • size of requests body is the same

Request content body is not compared instead only their size is

API

Attributes

chocs.HttpRequest.method : chocs.HttpMethod

Contains HTTP request's method for this request.

chocs.HttpRequest.path : str

Contains HTTP request's path for this request.

chocs.HttpRequest.query_string : chocs.HttpQueryString

Contains HTTP request's query string stored as dict like object.

chocs.HttpRequest.path_parameters : typing.Dict[str, str]

If route for the requests specifies any parameters like /user/{user_id}, those parameters can be accessed through path_parameters attribute.

chocs.HttpRequest.route : chocs.Route

Contains the route that was matched during processing HTTP request.

chocs.HttpRequest.attributes : typing.Dict[str, typing.Any]

Contains various attributes assigned by the environment in which chocs is running, eg.: aws_event or aws_context for AWS Lambda environment.

chocs.HttpRequest.headers : chocs.HttpHeaders

Contains dict like object which simplifies accessing HTTP request headers.

This attribute is read-only, every-time it is accessed the copy of locally stored headers are returned. Modifying this attribute will not have an effect on actual request object.

chocs.HttpRequest.cookies : chocs.HttpCookieJar

Contains HTTP request cookies stored as a dict like object.

This attribute is read-only, every-time it is accessed the copy of locally stored cookies are returned. Modifying this attribute will not have an effect on actual request object.

chocs.HttpRequest.body : io.BytesIO

Contains data sent by client stored as byte object.

chocs.HttpRequest.parsed_body : chocs.HttpMessage

Contains special interface to simplify working with request data.

Depending on the HTTP request's content type header parsed body might be an instance of one of the following classes:

  • chocs.FormHttpMessage for requests containing form data which content type header is set to application/x-www-form-urlencoded
  • chocs.MultipartHttpMessage for requests containing files and form data which content type header is set to multipart/form-data
  • chocs.JsonHttpMessage for requests with json data which content type header is set to application/json
  • chocs.YamlHttpMessage for request with yaml data which content type header is set to text/yaml, text/x-yaml, application/x-yaml

Methods

chocs.HttpRequest.as_str() -> str

Returns HTTP request's string representation.

chocs.HttpRequest.as_dict() -> dict

Returns HTTP request's dict representation if any available

Clone this wiki locally