Home | History | Annotate | Download | only in docs
      1 WebOb
      2 +++++
      3 
      4 .. toctree::
      5 
      6    reference
      7    modules/webob
      8    modules/dec
      9    modules/static
     10    modules/exceptions
     11    modules/client
     12    differences
     13    file-example
     14    wiki-example
     15    comment-example
     16    jsonrpc-example
     17    do-it-yourself
     18    news
     19    license
     20 
     21 .. contents::
     22 
     23 .. comment:
     24 
     25     >>> from doctest import ELLIPSIS
     26 
     27 
     28 Status & License
     29 ================
     30 
     31 WebOb is an extraction and refinement of pieces from `Paste
     32 <http://pythonpaste.org/>`_.  It is under active development.
     33 Discussion should happen on the `Paste mailing lists
     34 <http://pythonpaste.org/community/>`_, and bugs can go on the `issue tracker
     35 <https://github.com/Pylons/webob/issues>`_.  It was originally
     36 written by `Ian Bicking <http://ianbicking.org/>`_, and is being maintained
     37 by the `Pylons Project <http://www.pylonsproject.org/>`.
     38 
     39 WebOb is released under an `MIT-style license <license.html>`_.
     40 
     41 WebOb development happens on `GitHub <https://github.com/Pylons/webob>`_.
     42 Development version is installable via `easy_install
     43 webob==dev <https://github.com/Pylons/webob/zipball/master>`__.  You
     44 can clone the source code with::
     45 
     46     $ git clone https://github.com/Pylons/webob.git
     47 
     48 Introduction
     49 ============
     50 
     51 WebOb provides objects for HTTP requests and responses.  Specifically
     52 it does this by wrapping the `WSGI <http://wsgi.org>`_ request
     53 environment and response status/headers/app_iter(body).
     54 
     55 The request and response objects provide many conveniences for parsing
     56 HTTP request and forming HTTP responses.  Both objects are read/write:
     57 as a result, WebOb is also a nice way to create HTTP requests and
     58 parse HTTP responses; however, we won't cover that use case in this
     59 document.  The `reference documentation <reference.html>`_ shows many
     60 examples of creating requests.
     61 
     62 Request
     63 =======
     64 
     65 The request object is a wrapper around the `WSGI environ dictionary
     66 <http://www.python.org/dev/peps/pep-0333/#environ-variables>`_.  This
     67 dictionary contains keys for each header, keys that describe the
     68 request (including the path and query string), a file-like object for
     69 the request body, and a variety of custom keys.  You can always access
     70 the environ with ``req.environ``.
     71 
     72 Some of the most important/interesting attributes of a request
     73 object:
     74 
     75 ``req.method``:
     76     The request method, e.g., ``'GET'``, ``'POST'``
     77 
     78 ``req.GET``:
     79     A `dictionary-like object`_ with all the variables in the query
     80     string.
     81 
     82 ``req.POST``:
     83     A `dictionary-like object`_ with all the variables in the request
     84     body.  This only has variables if the request was a ``POST`` and
     85     it is a form submission.
     86 
     87 ``req.params``:
     88     A `dictionary-like object`_ with a combination of everything in
     89     ``req.GET`` and ``req.POST``.
     90 
     91 ``req.body``:
     92     The contents of the body of the request.  This contains the entire
     93     request body as a string.  This is useful when the request is a
     94     ``POST`` that is *not* a form submission, or a request like a
     95     ``PUT``.  You can also get ``req.body_file`` for a file-like
     96     object.
     97 
     98 ``req.cookies``:
     99     A simple dictionary of all the cookies.
    100 
    101 ``req.headers``:
    102     A dictionary of all the headers.  This is dictionary is case-insensitive.
    103 
    104 ``req.urlvars`` and ``req.urlargs``:
    105     ``req.urlvars`` is the keyword parameters associated with the
    106     request URL.  ``req.urlargs`` are the positional parameters.
    107     These are set by products like `Routes
    108     <http://routes.groovie.org/>`_ and `Selector
    109     <http://lukearno.com/projects/selector/>`_.
    110 
    111 .. _`dictionary-like object`: #multidict
    112 
    113 Also, for standard HTTP request headers there are usually attributes,
    114 for instance: ``req.accept_language``, ``req.content_length``,
    115 ``req.user_agent``, as an example.  These properties expose the
    116 *parsed* form of each header, for whatever parsing makes sense.  For
    117 instance, ``req.if_modified_since`` returns a `datetime
    118 <http://python.org/doc/current/lib/datetime-datetime.html>`_ object
    119 (or None if the header is was not provided).  Details are in the
    120 `Request reference <class-webob.Request.html>`_.
    121 
    122 URLs
    123 ----
    124 
    125 In addition to these attributes, there are several ways to get the URL
    126 of the request.  I'll show various values for an example URL
    127 ``http://localhost/app-root/doc?article_id=10``, where the application
    128 is mounted at ``http://localhost/app-root``.
    129 
    130 ``req.url``:
    131     The full request URL, with query string, e.g.,
    132     ``'http://localhost/app-root/doc?article_id=10'``
    133 
    134 ``req.application_url``:
    135     The URL of the application (just the SCRIPT_NAME portion of the
    136     path, not PATH_INFO).  E.g., ``'http://localhost/app-root'``
    137 
    138 ``req.host_url``:
    139     The URL with the host, e.g., ``'http://localhost'``
    140 
    141 ``req.relative_url(url, to_application=False)``:
    142     Gives a URL, relative to the current URL.  If ``to_application``
    143     is True, then resolves it relative to ``req.application_url``.
    144 
    145 Methods
    146 -------
    147 
    148 There are several methods in :class:`webob.Request` but only a few you'll use
    149 often:
    150 
    151 ``Request.blank(base_url)``:
    152     Creates a new request with blank information, based at the given
    153     URL.  This can be useful for subrequests and artificial requests.
    154     You can also use ``req.copy()`` to copy an existing request, or
    155     for subrequests ``req.copy_get()`` which copies the request but
    156     always turns it into a GET (which is safer to share for
    157     subrequests).
    158 
    159 ``req.get_response(wsgi_application)``:
    160     This method calls the given WSGI application with this request,
    161     and returns a `Response`_ object.  You can also use this for
    162     subrequests or testing.
    163 
    164 Unicode
    165 -------
    166 
    167 Many of the properties in the request object will return unicode
    168 values if the request encoding/charset is provided.  The client *can*
    169 indicate the charset with something like ``Content-Type:
    170 application/x-www-form-urlencoded; charset=utf8``, but browsers seldom
    171 set this.  You can set the charset with ``req.charset = 'utf8'``, or
    172 during instantiation with ``Request(environ, charset='utf8')``.  If
    173 you subclass ``Request`` you can also set ``charset`` as a class-level
    174 attribute.
    175 
    176 If it is set, then ``req.POST``, ``req.GET``, ``req.params``, and
    177 ``req.cookies`` will contain unicode strings.  Each has a
    178 corresponding ``req.str_*`` (like ``req.str_POST``) that is always
    179 ``str`` and never unicode.
    180 
    181 Response
    182 ========
    183 
    184 The response object looks a lot like the request object, though with
    185 some differences.  The request object wraps a single ``environ``
    186 object; the response object has three fundamental parts (based on
    187 WSGI):
    188 
    189 ``response.status``:
    190     The response code plus message, like ``'200 OK'``.  To set the
    191     code without the reason, use ``response.status_code = 200``.
    192 
    193 ``response.headerlist``:
    194     A list of all the headers, like ``[('Content-Type',
    195     'text/html')]``.  There's a case-insensitive `dictionary-like
    196     object`_ in ``response.headers`` that also allows you to access
    197     these same headers.
    198 
    199 ``response.app_iter``:
    200     An iterable (such as a list or generator) that will produce the
    201     content of the response.  This is also accessible as
    202     ``response.body`` (a string), ``response.unicode_body`` (a
    203     unicode object, informed by ``response.charset``), and
    204     ``response.body_file`` (a file-like object; writing to it appends
    205     to ``app_iter``).
    206 
    207 Everything else in the object derives from this underlying state.
    208 Here's the highlights:
    209 
    210 ``response.content_type``:
    211     The content type *not* including the ``charset`` parameter.
    212     Typical use: ``response.content_type = 'text/html'``.  You can
    213     subclass ``Response`` and add a class-level attribute
    214     ``default_content_type`` to set this automatically on
    215     instantiation.
    216 
    217 ``response.charset``:
    218     The ``charset`` parameter of the content-type, it also informs
    219     encoding in ``response.unicode_body``.
    220     ``response.content_type_params`` is a dictionary of all the
    221     parameters.
    222 
    223 ``response.request``:
    224     This optional attribute can point to the request object associated
    225     with this response object.
    226 
    227 ``response.set_cookie(key, value, max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None)``:
    228     Set a cookie.  The keyword arguments control the various cookie
    229     parameters.  The ``max_age`` argument is the length for the cookie
    230     to live in seconds (you may also use a timedelta object).  The
    231     `Expires`` key will also be set based on the value of ``max_age``.
    232 
    233 ``response.delete_cookie(key, path='/', domain=None)``:
    234     Delete a cookie from the client.  This sets ``max_age`` to 0 and
    235     the cookie value to ``''``.
    236 
    237 ``response.cache_expires(seconds=0)``:
    238     This makes this response cachable for the given number of seconds,
    239     or if ``seconds`` is 0 then the response is uncacheable (this also
    240     sets the ``Expires`` header).
    241 
    242 ``response(environ, start_response)``: The response object is a WSGI
    243     application.  As an application, it acts according to how you
    244     create it.  It *can* do conditional responses if you pass
    245     ``conditional_response=True`` when instantiating (or set that
    246     attribute later).  It can also do HEAD and Range requests.
    247 
    248 Headers
    249 -------
    250 
    251 Like the request, most HTTP response headers are available as
    252 properties.  These are parsed, so you can do things like
    253 ``response.last_modified = os.path.getmtime(filename)``.
    254 
    255 The details are available in the `extracted Response documentation
    256 <class-webob.Response.html>`_.
    257 
    258 Instantiating the Response
    259 --------------------------
    260 
    261 Of course most of the time you just want to *make* a response.
    262 Generally any attribute of the response can be passed in as a keyword
    263 argument to the class; e.g.:
    264 
    265 .. code-block:: python
    266 
    267   response = Response(body='hello world!', content_type='text/plain')
    268 
    269 The status defaults to ``'200 OK'``.  The content_type does not
    270 default to anything, though if you subclass ``Response`` and set
    271 ``default_content_type`` you can override this behavior.
    272 
    273 Exceptions
    274 ==========
    275 
    276 To facilitate error responses like 404 Not Found, the module
    277 ``webob.exc`` contains classes for each kind of error response.  These
    278 include boring but appropriate error bodies.
    279 
    280 Each class is named ``webob.exc.HTTP*``, where ``*`` is the reason for
    281 the error.  For instance, ``webob.exc.HTTPNotFound``.  It subclasses
    282 ``Response``, so you can manipulate the instances in the same way.  A
    283 typical example is:
    284 
    285 .. code-block:: python
    286 
    287     response = HTTPNotFound('There is no such resource')
    288     # or:
    289     response = HTTPMovedPermanently(location=new_url)
    290 
    291 You can use this like:
    292 
    293 .. code-block:: python
    294 
    295     try:
    296         ... stuff ...
    297         raise HTTPNotFound('No such resource')
    298     except HTTPException, e:
    299         return e(environ, start_response)
    300 
    301 The exceptions are still WSGI applications, but you cannot set
    302 attributes like ``content_type``, ``charset``, etc. on these exception
    303 objects.
    304 
    305 Multidict
    306 =========
    307 
    308 Several parts of WebOb use a "multidict"; this is a dictionary where a
    309 key can have multiple values.  The quintessential example is a query
    310 string like ``?pref=red&pref=blue``; the ``pref`` variable has two
    311 values: ``red`` and ``blue``.
    312 
    313 In a multidict, when you do ``request.GET['pref']`` you'll get back
    314 only ``'blue'`` (the last value of ``pref``).  Sometimes returning a
    315 string, and sometimes returning a list, is the cause of frequent
    316 exceptions.  If you want *all* the values back, use
    317 ``request.GET.getall('pref')``.  If you want to be sure there is *one
    318 and only one* value, use ``request.GET.getone('pref')``, which will
    319 raise an exception if there is zero or more than one value for
    320 ``pref``.
    321 
    322 When you use operations like ``request.GET.items()`` you'll get back
    323 something like ``[('pref', 'red'), ('pref', 'blue')]``.  All the
    324 key/value pairs will show up.  Similarly ``request.GET.keys()``
    325 returns ``['pref', 'pref']``.  Multidict is a view on a list of
    326 tuples; all the keys are ordered, and all the values are ordered.
    327 
    328 Example
    329 =======
    330 
    331 The `file-serving example <file-example.html>`_ shows how to do more
    332 advanced HTTP techniques, while the `comment middleware example
    333 <comment-example.html>`_ shows middleware.  For applications it's more
    334 reasonable to use WebOb in the context of a larger framework.  `Pylons
    335 <http://pylonshq.com>`_ uses WebOb in 0.9.7+.
    336 
    337 .. meta::
    338    :google-site-verification: 1oDd59jXPaC0wzgPn3g6cFMI-QvEHjkh8-2rlZeXqwc
    339