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
orPUT
data when available, otherwise querystring (GET
) data. Querystring data is always available via thequery
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 afresco.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 theJSONDecoder
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.
- 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
orhttps
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
andquery_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 ofquery
, 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
orPOST
.
- 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.