The Request Class

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

MultiDicts

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

>>> with app.requestcontext('/?a=Trinidad;b=Mexico;b=Honolulu') as c:
...     request = c.request
...     print(request.form.get('a'))
...     print(request.form.get('b'))
...     print(request.form.getlist('b'))
Trinidad
Mexico
['Mexico', 'Honolulu']

Form data

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

request.form["email"]
request.form.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.

The Request class has dictionary-like shortcuts to simplify accessing form data simpler:

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

The get() method can also do simple type conversion on incoming data, for example:

>>> with FrescoApp().requestcontext("?a=12") as c:
...     c.request.get("a")
...     c.request.get("a", type=int)
...     c.request.get("a", type=float)
...
'12'
12
12.0

Request body and JSON data

The raw byte data of the request is available via body_bytes. More generally useful is body, which decodes the byte string to a unicode string based on the stated encoding. Accessing this raises a BadRequest if the string could not be decoded.

JSON payloads may be accessed via get_json()

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
<fresco.util.http.HTTPMessage instance at ...>

>>> upload.headers['Content-Type']
'text/plain'

>>> upload.file.read()
'Here is a nice file upload for you'

>>> with open('/tmp/bar.data', 'wb') as f:
...     upload.save(f)
...

>>> upload.save('/tmp/foo.txt')

Maximum size limit

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

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

>>> 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

Fresco also supports overriding these limits on a per-request basis, although you must ensure that this happens before the request form data is parsed. After any code accesses request.form or request.files it is no longer possible to change the limits for that request.

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

Accessing the request object

Fresco maintains the request object in the global context object, that can be accessed from anywhere in your application:

from fresco import context
request = context.request

If there is no request in progress, this code will raise an AttributeError.

All objects stored in fresco.context are linked to the request cycle. fresco.context.request will always return the current request, even if your application is runs in a multi-threaded server that handles many concurrent requests.

You can store any object you like in the request context. For example, to use it to maintain a database connection that is linked to the current request:

database = create_database('sqlite:')
context.db_store = Store(database)

Any code later using context.db_store would then get a connection specific to the current request, isolated from any connection in use in for other requests.

API reference: fresco.request

fresco.request

The Request class models an incoming HTTP request, allowing access to HTTP headers and request data (eg query string or submitted form data).

class fresco.request.Request(environ)[source]

Models an HTTP request, given a WSGI environ dictionary.

IE_CONTENT_DISPOSITION_WORKAROUND = True

Support broken IE content-disposition escaping

MAX_MULTIPART_SIZE = 2097152

Maximum size for multipart/form-data encoded post data

MAX_SIZE = 16384

Maximum size for application/x-www-form-urlencoded post data, or maximum field size in multipart/form-data encoded data, not including file uploads

SESSION_ENV_KEY = 'beaker.session'

WSGI key for the session variable. The default value is configured for use with beaker

property application_url

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

Synopsis:

>>> from fresco import FrescoApp
>>> with FrescoApp().requestcontext(HTTP_HOST='example.com',
...                                 SCRIPT_NAME='/animals',
...                                 PATH_INFO='/lion.html') as c:
...     c.request.application_url
u'http://example.com/animals'
property cookies

Return a fresco.multidict.MultiDict of cookies read from the request headers:

>>> from fresco import FrescoApp
>>> with FrescoApp().requestcontext(
...     HTTP_COOKIE='''Customer="WILE_E_COYOTE";
...     Part="Rocket_0001";
...     Part="Catapult_0032"
... ''') as c:
...     request = c.request
...
>>> request.cookies.getlist('Customer')
['WILE_E_COYOTE']
>>> request.cookies.getlist('Part')
['Rocket_0001', 'Catapult_0032']

See rfc2109, section 4.4

default_charset = 'UTF-8'

Encoding used to decode WSGI parameters, notably PATH_INFO and form data

environ: Dict

The WSGI environ dict

property files

Return a MultiDict of all FileUpload objects available.

property form

Return the contents of submitted form data

This will return the POST or PUT data when available, otherwise querystring (GET) data. Querystring data is always available via the query property.

get(key, default=<object object>, type=None)[source]

Look up key in submitted form values.

Parameters:
  • type – The type to which the returned result should be converted

  • default – The value produced if the argument is missing

If type is specified and the value cannot be converted to the given type, or the value is not present and and no default value has been specified, then a fresco.exceptions.BadRequest error is raised.

get_header(name, default=None)[source]

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.

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 environment they appear as follows:

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

This method expects the former style (eg If-Modified-Since) and is not case sensitive.

get_json(*args, **kwargs)[source]

Return a decoded JSON request body.

*args and **kwargs are passed to the JSONDecoder constructor.

This will try to decode a json string regardless of the mime type sent by the client.

getint(key, default=<object object>) int[source]

Return the named key, converted to an integer.

If the key is not present or could not be converted to an int and no default is specified, BadRequest will be raised.

getlist(key)[source]

Return a list of submitted form values for key

property is_secure

Return True if the request is served over a secure connection.

json_decoder_class

The decoder class to use for JSON request payloads

alias of JSONDecoder

make_url(scheme: str | None = None, netloc: str | None = None, path: str | None = None, parameters: str | None = None, query: None | str | Mapping[str, Any] | Iterable[Tuple[str, Any]] = None, query_add: None | str | Mapping[str, Any] | Iterable[Tuple[str, Any]] = None, query_replace: None | str | Mapping[str, Any] | Iterable[Tuple[str, Any]] = None, fragment: str | None = None, SCRIPT_NAME: str | None = None, PATH_INFO: str | None = None, **kwargs) str[source]

Make a new URL based on the current URL, replacing any of the six URL elements (scheme, netloc, path, parameters, query or fragment). The current request’s query string is not included in the generated URL unless you explicitly pass it in.

Parameters:
  • scheme – The URL scheme, eg http or https

  • netloc – The netloc portion of the URL, eg ‘example.com:80’

  • path – The path portion of the URL, eg ‘/my/page.html’

  • parameters – RFC2396 path parameters (see also the stdlib urlparse module)

  • fragment – The URL fragment

  • query – Query data, as a list of tuples, a dict or a string. If supplied, any query parameters present in the current request’s url will be removed.

  • query_add – Query parameters to add. If the current url already contains query parameters with the same name, these will be supplemented with the new values.

  • query_replace – Query parameters to replace. If the current url already contains query parameters with the same name, these will be replaced with the new values.

  • PATH_INFO – The PATH_INFO portion of the path. Overrides path

  • SCRIPT_NAME – The SCRIPT_NAME portion of the path. Overrides path

  • kwargs – Any remaining keyword arguments are appended to the querystring

Return type:

str

All arguments (other than query related arguments, see examples below) must be strings (not bytes).

Examples:

Reproduce the request URL:

>>> from fresco import FrescoApp
>>> with FrescoApp().requestcontext(HTTP_HOST='example.com',
...                                 SCRIPT_NAME='/fruitsalad',
...                                 PATH_INFO='/banana',
...                                 QUERY_STRING='cream=n') as c:
...     request = c.request

>>> request.make_url(query=request.query)
u'http://example.com/fruitsalad/banana?cream=n'

Replace the URL scheme:

>>> request.make_url(scheme='ftp')
u'ftp://example.com/fruitsalad/banana'

Replace the entire path:

>>> request.make_url(path='/sausages')
u'http://example.com/sausages'

Replace just the path_info portion:

>>> request.make_url(PATH_INFO='/sausages')
u'http://example.com/fruitsalad/sausages'

Add a query string:

request.make_url(query={'portions': '2'}, cherries='n')
u'http://example.com/fruitsalad/banana?portions=2;cherries='n'

If a relative path is passed, the returned URL 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.make_url(path='kiwi')
u'http://example.com/fruitsalad/kiwi'

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

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

The query argument can take a dictionary, a list of (name, value) pairs or any other type convertable to a MultiDict:

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

>>> request.make_url(query={'a': 'tokyo', 'b': 'milan'})
u'http://example.com/fruitsalad/banana?a=tokyo;b=milan'

>>> request.make_url(query=[('a', 'tokyo'),
...                         ('b', 'milan'),
...                         ('b', 'paris')])
u'http://example.com/fruitsalad/banana?a=tokyo;b=milan;b=paris'

The query_add and query_replace arguments add or replace values in an existing query string. If either of these is specified then the current request’s query string (or value of query, if specified) will be extended with the given values. These arguments take a dict, a list of (key, value) tuples, or any other type convertable to a MultiDict.

property method

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

property now

Return a timezone-aware UTC datetime instance. The value returned is guaranteed to be constant throughout the lifetime of the request.

property parsed_url

Return the current URL as a tuple of the form:

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

Synopsis:

>>> from fresco import FrescoApp
>>> app = FrescoApp()
>>> with app.requestcontext(
...          'https://example.com/animals/view?name=lion') as c:
...     c.request.parsed_url  
ParseResult(scheme=u'https', netloc=u'example.com', ...)

Components are returned as unicode strings

property path

Return the path component of the requested URL

property path_info: str

The PATH_INFO value as a string

Note that PATH_INFO is already unquoted by the server

property query: MultiDict

Return a MultiDict of any querystring submitted data.

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

Synopsis:

>>> from fresco import FrescoApp
>>> with FrescoApp().requestcontext('/?animal=moose') as c:
...     c.request.query['animal']
u'moose'

This property always returns querystring data, regardless of the request method used.

property query_string: str | None

The QUERY_STRING value as a unicode string

property referrer

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

property remote_addr

Return the remote address of the client

resolve_url(url, relative='app')[source]

Resolve a partially qualified URL in context of the current request.

Parameters:
  • url – A url, may be fully or partially qualified

  • relative – One of ‘app’ or ‘server’

Returns:

A fully qualified URL

Examples:

>>> from fresco import FrescoApp
>>> app = FrescoApp()
>>> with app.requestcontext('http://example.net/foo/bar') as c:
...     request = c.request
...
>>> request.resolve_url('/baz')
'http://example.net/baz'
>>> request.resolve_url('baz')
'http://example.net/foo/baz'
>>> request.resolve_url('http://anotherhost/bar')
'http://anotherhost/bar'

The returned URL path will be normalized:

>>> app = FrescoApp()
>>> with app.requestcontext('http://example.net/foo/bar') as c:
...     c.request.resolve_url('../bar')
...
'http://example.net/bar'

URLs can be resolved relative to the application’s base URL (including SCRIPT_NAME) or the server root via the relative argument:

>>> from fresco import FrescoApp
>>> app = FrescoApp()
>>> with app.requestcontext(SCRIPT_NAME='/foo',
...                         PATH_INFO='bar') as c:
...     request = c.request
>>> request.resolve_url('/baz', relative='app')
'http://localhost/foo/baz'
>>> request.resolve_url('/baz', relative='server')
'http://localhost/baz'

If not specified, application relative paths will be assumed.

property script_name

The SCRIPT_NAME value as a unicode string

Note that SCRIPT_NAME is already unquoted by the server

property session

Return the session associated with this request.

Requires a session object to have been inserted into the WSGI environment by a middleware application.

teardown_handlers: List[Callable]

List of functions to be called at the end of this request’s lifecycle

property url

Return the full URL, including query parameters.

fresco.request.currentrequest()[source]

Return the current value of context.request, or None if there is no request in scope.