Changed location of the svn command in svn_load_dirs.pl script from '/usr/bin/svn' to 'svn'. That makes the script more universal and it should work on Linux, Windows and Mac OS X if the svn is in the PATH.
Patch by: Pawel Solyga
Review by: to-be-reviewed
WebOb+++++Other documents:* `Reference <reference.html>`_* Extracted documentation for the `request <class-webob.Request.html>`_ and `response <class-webob.Response.html>`_.* `Differences between the WebOb API and other framework/libraries <differences.html>`_* `File-serving example <file-example.html>`_* `Comment middleware example <comment-example.html>`_.. contents::.. comment: >>> from dtopt import ELLIPSISStatus & License================WebOb is an extraction and refinement of pieces from `Paste<http://pythonpaste.org/>`_. It is under active development.Discussion should happen on the `Paste mailing lists<http://pythonpaste.org/community/>`_, and bugs can go on the `Pastetrac instance <http://trac.pythonpaste.org/>`_.WebOb is released under an `MIT-style license <license.html>`_.WebOb is in an svn repository at`http://svn.pythonpaste.org/Paste/WebOb/trunk<http://svn.pythonpaste.org/Paste/WebOb/trunk#egg=WebOb-dev>`_. Youcan check it out with:: $ svn co http://svn.pythonpaste.org/Paste/WebOb/trunk WebObIntroduction============WebOb provides objects for HTTP requests and responses. Specificallyit does this by wrapping the `WSGI <http://wsgi.org>`_ requestenvironment and response status/headers/app_iter(body).The request and response objects provide many conveniences for parsingHTTP request and forming HTTP responses. Both objects are read/write:as a result, WebOb is also a nice way to create HTTP requests andparse HTTP responses; however, we won't cover that use case in thisdocument. The `reference documentation <reference.html>`_ shows manyexamples of creating requests.Request=======The request object is a wrapper around the `WSGI environ dictionary<http://www.python.org/dev/peps/pep-0333/#environ-variables>`_. Thisdictionary contains keys for each header, keys that describe therequest (including the path and query string), a file-like object forthe request body, and a variety of custom keys. You can always accessthe environ with ``req.environ``.Some of the most important/interesting attributes of a requestobject:``req.method``: The request method, e.g., ``'GET'``, ``'POST'````req.GET``: A `dictionary-like object`_ with all the variables in the query string.``req.POST``: A `dictionary-like object`_ with all the variables in the request body. This only has variables if the request was a ``POST`` and it is a form submission. ``req.params``: A `dictionary-like object`_ with a combination of everything in ``req.GET`` and ``req.POST``.``req.body``: The contents of the body of the request. This contains the entire request body as a string. This is useful when the request is a ``POST`` that is *not* a form submission, or a request like a ``PUT``. You can also get ``req.body_file`` for a file-like object.``req.cookies``: A simple dictionary of all the cookies.``req.headers``: A dictionary of all the headers. This is dictionary is case-insensitive... _`dictionary-like object`: #multidictAlso, for standard HTTP request headers there are usually attributes,for instance: ``req.accept_language``, ``req.content_length``,``req.user_agent``, as an example. These properties expose the*parsed* form of each header, for whatever parsing makes sense. Forinstance, ``req.if_modified_since`` returns a `datetime<http://python.org/doc/current/lib/datetime-datetime.html>`_ object(or None if the header is was not provided). Details are in the`Request reference <class-webob.Request.html>`_.URLs----In addition to these attributes, there are several ways to get the URLof the request. I'll show various values for an example URL``http://localhost/app-root/doc?article_id=10``, where the applicationis mounted at ``http://localhost/app-root``.``req.url``: The full request URL, with query string, e.g., ``'http://localhost/app-root/doc?article_id=10'````req.application_url``: The URL of the application (just the SCRIPT_NAME portion of the path, not PATH_INFO). E.g., ``'http://localhost/app-root'````req.host_url``: The URL with the host, e.g., ``'http://localhost'````req.relative_url(url, to_application=False)``: Gives a URL, relative to the current URL. If ``to_application`` is True, then resolves it relative to ``req.application_url``.Methods-------There are `several methods <class-webob.Request.html#__init__>`_ butonly a few you'll use often:``Request.blank(base_url)``: Creates a new request with blank information, based at the given URL. This can be useful for subrequests and artificial requests. You can also use ``req.copy()`` to copy an existing request, or for subrequests ``req.copy_get()`` which copies the request but always turns it into a GET (which is safer to shrae for subrequests).``req.get_response(wsgi_application)``: This method calls the given WSGI application with this request, and returns a `Response`_ object. You can also use this for subrequests or testing.Unicode-------Many of the properties in the request object will return unicodevalues if the request encoding/charset is provided. The client *can*indicate the charset with something like ``Content-Type:application/x-www-form-urlencoded; charset=utf8``, but browsers seldomset this. You can set the charset with ``req.charset = 'utf8'``, orduring instantiation with ``Request(environ, charset='utf8'). If yousubclass ``Request`` you can also set ``charset`` as a class-levelattribute.If it is set, then ``req.POST``, ``req.GET``, ``req.params``, and``req.cookies`` will contain unicode strings. Each has acorresponding ``req.str_*`` (like ``req.str_POST``) that is always``str`` and never unicode.Response========The response object looks a lot like the request object, though withsome differences. The request object wraps a single ``environ``object; the response object has three fundamental parts (based onWSGI):``response.status``: The response code plus message, like ``'200 OK'``. To set the code without the reason, use ``response.status_int = 200``.``response.headerlist``: A list of all the headers, like ``[('Content-Type', 'text/html')]``. There's a case-insensitive `dictionary-like object`_ in ``response.headers`` that also allows you to access these same headers.``response.app_iter``: An iterable (such as a list or generator) that will produce the content of the response. This is also accessible as ``response.body`` (a string), ``response.unicode_body`` (a unicode object, informed by ``response.charset``), and ``response.body_file`` (a file-like object; writing to it appends to ``app_iter``).Everything else in the object derives from this underlying state.Here's the highlights:``response.content_type``: The content type *not* including the ``charset`` parameter. Typical use: ``response.content_type = 'text/html'``. You can subclass ``Response`` and add a class-level attribute ``default_content_type`` to set this automatically on instantiation.``response.charset``: The ``charset`` parameter of the content-type, it also informs encoding in ``response.unicode_body``. ``response.content_type_params`` is a dictionary of all the parameters.``response.request``: This optional attribute can point to the request object associated with this response object.``response.set_cookie(key, value, max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None)``: Set a cookie. The keyword arguments control the various cookie parameters.``response.delete_cookie(key, path='/', domain=None)``: Delete a cookie from the client. This sets ``max_age`` to 0 and the cookie value to ``''``.``response.cache_expires(seconds=0)``: This makes this response cachable for the given number of seconds, or if ``seconds`` is 0 then the response is uncacheable (this also sets the ``Expires`` header).``response(environ, start_response)``: The response object is a WSGI application. As an application, it acts according to how you creat it. It *can* do conditional responses if you pass ``conditional_response=True`` when instantiating (or set that attribute later). It can also do HEAD and Range requests.Headers-------Like the request, most HTTP response headers are available asproperties. These are parsed, so you can do things like``response.last_modified = os.path.getmtime(filename)``.The details are available in the `extracted Response documentation<class-webob.Response.html>`_.Instantiating the Response--------------------------Of course most of the time you just want to *make* a response. Generally any attribute of the response can be passed in as a keywordargument to the class; e.g.:.. code-block:: response = Response(body='hello world!', content_type='text/plain')The status defaults to ``'200 OK'``. The content_type does notdefault to anything, though if you subclass ``Response`` and set``default_content_type`` you can override this behavior.Exceptions==========To facilitate error responses like 404 Not Found, the module``webob.exc`` contains classes for each kind of error response. Theseinclude boring but appropriate error bodies.Each class is named ``webob.exc.HTTP*``, where ``*`` is the reason forthe error. For instance, ``webob.exc.HTTPNotFound``. It subclasses``Response``, so you can manipulate the instances in the same way. Atypical example is:.. code-block:: response = HTTPNotFound('There is no such resource') # or: response = HTTPMovedPermanently(location=new_url)These are not exceptions unless you are using Python 2.5+, becausethey are new-style classes which are not allowed as exceptions untilPython 2.5. To get an exception object use ``response.exception``.You can use this like:.. code-block:: try: ... stuff ... raise HTTPNotFound('No such resource').exception except HTTPException, e: return e(environ, start_response)The exceptions are still WSGI applications, but you cannot setattributes like ``content_type``, ``charset``, etc. on these exceptionobjects.Multidict=========Several parts of WebOb use a "multidict"; this is a dictionary where akey can have multiple values. The quintessential example is a querystring like ``?pref=red&pref=blue``; the ``pref`` variable has twovalues: ``red`` and ``blue``.In a multidict, when you do ``request.GET['pref']`` you'll get backonly ``'blue'`` (the last value of ``pref``). Sometimes returning astring, and sometimes returning a list, is the cause of frequentexceptions. If you want *all* the values back, use``request.GET.getall('pref')``. If you want to be sure there is *oneand only one* value, use ``request.GET.getone('pref')``, which willraise an exception if there is zero or more than one value for``pref``.When you use operations like ``request.GET.items()`` you'll get backsomething like ``[('pref', 'red'), ('pref', 'blue')]``. All thekey/value pairs will show up. Similarly ``request.GET.keys()``returns ``['pref', 'pref']``. Multidict is a view on a list oftuples; all the keys are ordered, and all the values are ordered.Example=======I haven't figured out the example I want to use here. The`file-serving example`_ shows how to do more advanced HTTP techniques,while the `comment middleware example`_ shows middleware. Forapplications it's more reasonable to use WebOb in the context of alarger framework. `Pylons <http://pylonshq.com>`_ uses WebOboptionally in 0.9.7+.