The request object

The request object gives access to all WSGI environment properties, including request headers and server variables, as well as submitted form data.

Core WSGI environment variables and other useful information is exposed as attributes:

>>> from pesto.request import Request
>>> environ = {
...     'PATH_INFO': '/pages/index.html',
...     'SCRIPT_NAME': '/myapp',
...     'REQUEST_METHOD': 'GET',
...     'SERVER_PROTOCOL': 'http',
...     'SERVER_NAME': 'example.org',
...     'SERVER_PORT': '80'
... }
>>> request = Request(environ)
>>> request.script_name
'/myapp'
>>> request.path_info
'/pages/index.html'
>>> request.application_uri
'http://example.org/myapp'

The API documentation at the end of this page contains the complete list of request attributes.

MultiDicts

Many items of data accessible through the request object are exposed as instances of pesto.utils.MultiDict. This has a dictionary-like interface, with additional methods for retrieving data where a key has multiple values associated with it. For example:

>>> from pesto.testing import TestApp, make_environ
>>> from pesto.request import Request
>>> request = Request(make_environ(QUERY_STRING='a=Trinidad;b=Mexico;b=Honolulu'))
>>> request.form.get('a')
u'Trinidad'
>>> request.form.get('b')
u'Mexico'
>>> request.form.getlist('b')
[u'Mexico', u'Honolulu']

Form data

Form values are accessible from request.form, a pesto.utils.MultiDict object, giving dictionary like access to submitted form data:

request.form["email"]
request.form.get("email")

As this is a very common usage, shortcuts exist:

request["email"]
request.get("email")

For GET requests, request.form contains data parsed from the URL query string. For POST requests, request.form contains only POSTED data. If a query string was present in a POST request, it is necessary to use request.query to access this, which has the same interface.

File uploads

The request.files dictionary has the same interface as request.form, but values are FileUpload objects, which allow you to access information about uploaded files as well as the raw data:

>>> upload = request.files['fileupload']
>>> upload.filename
'uploaded.txt'
>>> upload.file 
<cStringIO.StringO object at ...>
>>> upload.headers 
<pesto.httputils.HTTPMessage instance at ...>
>>> upload.headers['Content-Type']
'text/plain'
>>> upload.file.read()
'Here is a nice file upload for you'

Maximum size limit

Posted data, including file uploads, is limited in size. This limit can be altered by adjusting pesto.request.Request.MAX_SIZE and pesto.request.Request.MAX_MULTIPART_SIZE.

Example 1 – set the global maximum size for POSTed data to 100kb:

>>> from pesto.request import Request
>>> kb = 1024
>>> Request.MAX_SIZE = 100 * kb

Example 2 – set the global maximum size for multipart/form-data POSTs to 4Mb.

The total size data uploaded, including all form fields and file uploads will be limited to 4Mb. Individual fields (except file uploads) will be limited to 100Kb by the MAX_SIZE set in the previous example:

>>> Mb = 1024 * kb
>>> Request.MAX_MULTIPART_SIZE = 4 * Mb

Pesto also supports overriding these limits on a per-request basis:

>>> def big_file_upload(request):
...     request.MAX_MULTIPART_SIZE = 100 * Mb
...     request.files['bigfile'].save('/tmp/bigfile.bin')
...     return Response(["Thanks for uploading a big file"])
...

pesto.request API documention

pesto.request

Request object for WSGI applications.

class pesto.request.Request

Models an HTTP request, given a WSGI environ dictionary.

application_uri

Return the base URI of the WSGI application (ie the URI up to SCRIPT_NAME, but not including PATH_INFO or query information).

Synopsis:

>>> from pesto.testing import make_environ
>>> request = Request(make_environ(SCRIPT_NAME='/animals', PATH_INFO='/alligator.html'))
>>> request.application_uri
'http://localhost/animals'
content_type

HTTP Content-Type header

cookies

Return a pesto.utils.MultiDict of cookies read from the request headers:

>>> from pesto.testing import TestApp
>>> request = Request(TestApp.make_environ(
...     HTTP_COOKIE='''$Version="1";
...     Customer="WILE_E_COYOTE";
...     Part="Rocket_0001";
...     Part="Catapult_0032"
... '''))
>>> [c.value for c in request.cookies.getlist('Customer')]
['WILE_E_COYOTE']
>>> [c.value for c in request.cookies.getlist('Part')]
['Rocket_0001', 'Catapult_0032']

See rfc2109, section 4.4

document_root

Server document root

files

Return FileUpload objects for all uploaded files

form

Return the contents of any submitted form data

If the form has been submitted via POST, GET parameters are also available via Request.query.

get(key, default=None)

Look up key in submitted form values

get_header(name, default=None)

Return an arbitrary HTTP header from the request.

Parameters:
  • name – HTTP header name, eg ‘User-Agent’ or ‘If-Modified-Since’.
  • default – default value to return if the header is not set.

Technical note:

Headers in the original HTTP request are always formatted like this:

If-Modified-Since: Thu, 04 Jan 2007 21:41:08 GMT

However, in the WSGI environ dictionary they appear as follows:

{
    ...
    'HTTP_IF_MODIFIED_SINCE': 'Thu, 04 Jan 2007 21:41:08 GMT'
    ...
}

Despite this, this method expects the former formatting (with hyphens), and is not case sensitive.

getlist(key)

Return a list of submitted form values for key

make_uri(scheme=None, netloc=None, path=None, parameters=None, query=None, fragment=None, script_name=None, path_info=None)

Make a new URI based on the current URI, replacing any of the six URI elements (scheme, netloc, path, parameters, query or fragment)

A path_info argument can also be given instead of the path argument. In this case the generated URI path will be <SCRIPT_NAME>/<path_info>.

Synopsis:

Calling request.make_uri with no arguments will return the current URI:

>>> from pesto.testing import make_environ
>>> request = Request(make_environ(HTTP_HOST='example.com', SCRIPT_NAME='', PATH_INFO='/foo'))
>>> request.make_uri()
'http://example.com/foo'

Using keyword arguments it is possible to override any part of the URI:

>>> request.make_uri(scheme='ftp')
'ftp://example.com/foo'

>>> request.make_uri(path='/bar')
'http://example.com/bar'

>>> request.make_uri(query={'page' : '2'})
'http://example.com/foo?page=2'

If you just want to replace the PATH_INFO part of the URI, you can pass path_info to the make_uri. This will generate a URI relative to wherever your WSGI application is mounted:

>>> # Sample environment for an application mounted at /fruitsalad
>>> env = make_environ(
...     HTTP_HOST='example.com',
...     SCRIPT_NAME='/fruitsalad',
...     PATH_INFO='/banana'
... )
>>> Request(env).make_uri(path_info='/kiwi')
'http://example.com/fruitsalad/kiwi'

The path and query values are URL escaped before being returned:

>>> request.make_uri(path=u'/caff\u00e8 latte')
'http://example.com/caff%C3%A8%20latte'

The query argument can be a string, a dictionary, a MultiDict, or a list of (name, value) tuples:

>>> request.make_uri(query=u'a=tokyo&b=milan')
'http://example.com/foo?a=tokyo&b=milan'

>>> request.make_uri(query={'a': 'tokyo', 'b': 'milan'})
'http://example.com/foo?a=tokyo;b=milan'

>>> request.make_uri(query=MultiDict([('a', 'tokyo'), ('b', 'milan'), ('b', 'paris')]))
'http://example.com/foo?a=tokyo;b=milan;b=paris'

>>> request.make_uri(query=[('a', 'tokyo'), ('b', 'milan'), ('b', 'paris')])
'http://example.com/foo?a=tokyo;b=milan;b=paris'

If a relative path is passed, the returned URI is joined to the old in the same way as a web browser would interpret a relative HREF in a document at the current location:

>>> request = Request(make_environ(HTTP_HOST='example.com', SCRIPT_NAME='', PATH_INFO='/banana/milkshake'))
>>> request.make_uri(path='pie')
'http://example.com/banana/pie'

>>> request.make_uri(path='../strawberry')
'http://example.com/strawberry'

>>> request.make_uri(path='../../../plum')
'http://example.com/plum'

Note that a URI with a trailing slash will have different behaviour from one without a trailing slash:

>>> request = Request(make_environ(HTTP_HOST='example.com', SCRIPT_NAME='', PATH_INFO='/banana/milkshake/'))
>>> request.make_uri(path='mmmm...')
'http://example.com/banana/milkshake/mmmm...'

>>> request = Request(make_environ(HTTP_HOST='example.com', SCRIPT_NAME='', PATH_INFO='/banana/milkshake'))
>>> request.make_uri(path='mmmm...')
'http://example.com/banana/mmmm...'
parsed_uri

Returns the current URI as a tuple of the form:

(
 addressing scheme, network location, path,
 parameters, query, fragment identifier
)

Synopsis:

>>> from pesto.testing import make_environ
>>> request = Request(make_environ(
...     wsgi_url_scheme = 'https',
...     HTTP_HOST = 'example.com',
...     SCRIPT_NAME = '/animals',
...     PATH_INFO = '/view',
...     SERVER_PORT = '443',
...     QUERY_STRING = 'name=alligator'
... ))
>>> request.parsed_uri
('https', 'example.com', '/animals/view', '', 'name=alligator', '')

Note that the port number is stripped if the addressing scheme is ‘http’ and the port is 80, or the scheme is https and the port is 443:

>>> request = Request(make_environ(
...     wsgi_url_scheme = 'http',
...     HTTP_HOST = 'example.com:80',
...     SCRIPT_NAME = '/animals',
...     PATH_INFO = '/view',
...     QUERY_STRING = 'name=alligator'
... ))
>>> request.parsed_uri
('http', 'example.com', '/animals/view', '', 'name=alligator', '')
path_info

WSGI PATH_INFO value

query

Return a MultiDict of any querystring submitted data.

This is available regardless of whether the original request was a GET request.

Synopsis:

>>> from pesto.testing import TestApp
>>> request = Request(TestApp.make_environ(QUERY_STRING="animal=moose"))
>>> request.query.get('animal')
u'moose'

Note that this property is unaffected by the presence of POST data:

>>> from pesto.testing import TestApp
>>> from StringIO import StringIO
>>> postdata = 'animal=hippo'
>>> request = Request(TestApp.make_environ(
...     QUERY_STRING="animal=moose",
...     REQUEST_METHOD="POST",
...     CONTENT_TYPE = "application/x-www-form-urlencoded; charset=UTF-8",
...     CONTENT_LENGTH=len(postdata),
...     wsgi_input=postdata
... ))
>>> request.form.get('animal')
u'hippo'
>>> request.query.get('animal')
u'moose'
query_string

WSGI QUERY_STRING value

referrer

Return the HTTP referer header, or None if this is not available.

remote_addr

WSGI REMOTE_ADDR value

request_method

Return the HTTP method used for the request, eg GET or POST.

request_path

Return the path component of the requested URI

request_uri

Return the absolute URI, including query parameters.

script_name

WSGI SCRIPT_NAME value

server_name

WSGI SERVER_NAME value

session

Return the session associated with this request.

Requires a session object to have been inserted into the WSGI environment by a middleware application (see pesto.session.base.sessioning_middleware for an example).

text()

Return a useful text representation of the request

user_agent

Return the HTTP user agent header, or None if this is not available.

pesto.request.currentrequest()

Return the current Request object, or None if no request object is available.

Table Of Contents

Previous topic

Getting started with Pesto

Next topic

The response object

This Page