1WebOb 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 28Status & License 29================ 30 31WebOb is an extraction and refinement of pieces from `Paste 32<http://pythonpaste.org/>`_. It is under active development. 33Discussion 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 36written by `Ian Bicking <http://ianbicking.org/>`_, and is being maintained 37by the `Pylons Project <http://www.pylonsproject.org/>`. 38 39WebOb is released under an `MIT-style license <license.html>`_. 40 41WebOb development happens on `GitHub <https://github.com/Pylons/webob>`_. 42Development version is installable via `easy_install 43webob==dev <https://github.com/Pylons/webob/zipball/master>`__. You 44can clone the source code with:: 45 46 $ git clone https://github.com/Pylons/webob.git 47 48Introduction 49============ 50 51WebOb provides objects for HTTP requests and responses. Specifically 52it does this by wrapping the `WSGI <http://wsgi.org>`_ request 53environment and response status/headers/app_iter(body). 54 55The request and response objects provide many conveniences for parsing 56HTTP request and forming HTTP responses. Both objects are read/write: 57as a result, WebOb is also a nice way to create HTTP requests and 58parse HTTP responses; however, we won't cover that use case in this 59document. The `reference documentation <reference.html>`_ shows many 60examples of creating requests. 61 62Request 63======= 64 65The request object is a wrapper around the `WSGI environ dictionary 66<http://www.python.org/dev/peps/pep-0333/#environ-variables>`_. This 67dictionary contains keys for each header, keys that describe the 68request (including the path and query string), a file-like object for 69the request body, and a variety of custom keys. You can always access 70the environ with ``req.environ``. 71 72Some of the most important/interesting attributes of a request 73object: 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 113Also, for standard HTTP request headers there are usually attributes, 114for 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 117instance, ``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 122URLs 123---- 124 125In addition to these attributes, there are several ways to get the URL 126of the request. I'll show various values for an example URL 127``http://localhost/app-root/doc?article_id=10``, where the application 128is 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 145Methods 146------- 147 148There are several methods in :class:`webob.Request` but only a few you'll use 149often: 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 164Unicode 165------- 166 167Many of the properties in the request object will return unicode 168values if the request encoding/charset is provided. The client *can* 169indicate the charset with something like ``Content-Type: 170application/x-www-form-urlencoded; charset=utf8``, but browsers seldom 171set this. You can set the charset with ``req.charset = 'utf8'``, or 172during instantiation with ``Request(environ, charset='utf8')``. If 173you subclass ``Request`` you can also set ``charset`` as a class-level 174attribute. 175 176If it is set, then ``req.POST``, ``req.GET``, ``req.params``, and 177``req.cookies`` will contain unicode strings. Each has a 178corresponding ``req.str_*`` (like ``req.str_POST``) that is always 179``str`` and never unicode. 180 181Response 182======== 183 184The response object looks a lot like the request object, though with 185some differences. The request object wraps a single ``environ`` 186object; the response object has three fundamental parts (based on 187WSGI): 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 207Everything else in the object derives from this underlying state. 208Here'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 248Headers 249------- 250 251Like the request, most HTTP response headers are available as 252properties. These are parsed, so you can do things like 253``response.last_modified = os.path.getmtime(filename)``. 254 255The details are available in the `extracted Response documentation 256<class-webob.Response.html>`_. 257 258Instantiating the Response 259-------------------------- 260 261Of course most of the time you just want to *make* a response. 262Generally any attribute of the response can be passed in as a keyword 263argument to the class; e.g.: 264 265.. code-block:: python 266 267 response = Response(body='hello world!', content_type='text/plain') 268 269The status defaults to ``'200 OK'``. The content_type does not 270default to anything, though if you subclass ``Response`` and set 271``default_content_type`` you can override this behavior. 272 273Exceptions 274========== 275 276To facilitate error responses like 404 Not Found, the module 277``webob.exc`` contains classes for each kind of error response. These 278include boring but appropriate error bodies. 279 280Each class is named ``webob.exc.HTTP*``, where ``*`` is the reason for 281the error. For instance, ``webob.exc.HTTPNotFound``. It subclasses 282``Response``, so you can manipulate the instances in the same way. A 283typical 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 291You 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 301The exceptions are still WSGI applications, but you cannot set 302attributes like ``content_type``, ``charset``, etc. on these exception 303objects. 304 305Multidict 306========= 307 308Several parts of WebOb use a "multidict"; this is a dictionary where a 309key can have multiple values. The quintessential example is a query 310string like ``?pref=red&pref=blue``; the ``pref`` variable has two 311values: ``red`` and ``blue``. 312 313In a multidict, when you do ``request.GET['pref']`` you'll get back 314only ``'blue'`` (the last value of ``pref``). Sometimes returning a 315string, and sometimes returning a list, is the cause of frequent 316exceptions. If you want *all* the values back, use 317``request.GET.getall('pref')``. If you want to be sure there is *one 318and only one* value, use ``request.GET.getone('pref')``, which will 319raise an exception if there is zero or more than one value for 320``pref``. 321 322When you use operations like ``request.GET.items()`` you'll get back 323something like ``[('pref', 'red'), ('pref', 'blue')]``. All the 324key/value pairs will show up. Similarly ``request.GET.keys()`` 325returns ``['pref', 'pref']``. Multidict is a view on a list of 326tuples; all the keys are ordered, and all the values are ordered. 327 328Example 329======= 330 331The `file-serving example <file-example.html>`_ shows how to do more 332advanced HTTP techniques, while the `comment middleware example 333<comment-example.html>`_ shows middleware. For applications it's more 334reasonable 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