Replacement for twisted.web.iweb.IRequest
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Build Status Code Coverage Requirements Status Python Version Compatibility

txrequest is a library containing an HTTP Request object API for Twisted, meant to replace the IRequest interface and implementations in twisted.web.

txrequest is not an attempt at a an async version of requests. For that, see treq.

txrequest and Klein

The intention is for this new API to work its way into Klein (and possibly twisted.web) inconjunction with a new API for route handler methods. In the interim, a txroute decorator is provided to stack under Klein.route.

In Klein today, you might something write this code:

def hello(self, request: IRequest) -> str:
    Say hello.
    who = request.getHeader(b"User-Agent").decode("iso-8859-1")
    body = "Hello, {}!".format(who)


    request.setHeader("Content-Type", "text/plain; charset=UTF-8")
    request.setHeader("ETag", "0")

    return message.encode("utf-8")

Above, the author indicates the desired response code and response headers by setting them onto the request object.

This is an odd abstraction; the request represents the request data from the client, not the response data sent to the client, and it arguably should be immutable. Worse, getHeader looks up a value in the request headers, where setHeader sets a value in the response headers.

Also, the response body is provided as it's own return value, disconnected from the response code and headers. This is problematic in cases where a response

Finally, this API requires that header data be expressed as bytes instead of text.

The new API takes an IHTTPRequest and returns a IHTTPResponse:

def hello(self, request: IHTTPRequest) -> IHTTPResponse:
    Say hello.
    who = request.headers.getValues("User-Agent")[-1:]
    message = "Hello, {}!".format(who)

    headers = MutableHTTPHeaders()
    headers.addValue("Content-Type", "text/plain; charset=UTF-8")
    headers.addValue("ETag", "0")

    return FrozenHTTPResponse(

Here a single response object, encapsulating the entire response is returned.

Request Object

For testing, creating a request object in the new API is straightforward:

request = FrozenHTTPRequest(
    method = "GET",
    uri = URL.fromText("/foo"),
    headers = FrozenHTTPHeaders(
        ("X-Foo", "Foo Value"),
        ("X-Bar", "Bar Value"),

Creating an IRequest is not as straightforward.