diff -r 261778de26ff -r 620f9b141567 thirdparty/google_appengine/lib/webob/docs/differences.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thirdparty/google_appengine/lib/webob/docs/differences.txt Tue Aug 26 21:49:54 2008 +0000 @@ -0,0 +1,590 @@ +Differences Between WebOb and Other Systems ++++++++++++++++++++++++++++++++++++++++++++ + +This document points out some of the API differences between the +Request and Response object, and the objects in other systems. + +.. contents:: + +paste.wsgiwrappers and Pylons +============================= + +The Pylons ``request`` and ``response`` object are based on +``paste.wsgiwrappers.WSGIRequest`` and ``WSGIResponse`` + +There is no concept of ``defaults`` in WebOb. In Paste/Pylons these +serve as threadlocal settings that control certain policies on the +request and response object. In WebOb you should make your own +subclasses to control policy (though in many ways simply being +explicit elsewhere removes the need for this policy). + +Request +------- + +``body``: + This is a file-like object in WSGIRequest. In WebOb it is a + string (to match Response.body) and the file-like object is + available through ``req.body_file`` + +``languages()``: + This is available through ``req.accept_language``, particularly + ``req.accept_language.best_matches(fallback_language)`` + +``match_accept(mimetypes)``: + This is available through ``req.accept.first_match(mimetypes)``; + or if you trust the client's quality ratings, you can use + ``req.accept.best_match(mimetypes)`` + +``errors``: + This controls how unicode decode errors are handled; it is now + named ``unicode_errors`` + +There are also many extra methods and attributes on WebOb Request +objects. + +Response +-------- + +default ``content_type``: + The base Response object has no default content_type or charset. + You can set ``default_content_type`` in a subclass. + +``determine_charset()``: + Is now available as ``res.charset`` + +``has_header(header)``: + Should be done with ``header in res.headers`` + +``get_content()`` and ``wsgi_response()``: + These are gone; you should use ``res.body`` or ``res(environ, + start_response)`` + +``write(content)``: + Available in ``res.body_file.write(content)``. + +``flush()`` and ``tell()``: + Not available. + +There are also many extra methods and attributes on WebOb Response +objects. + +Django +====== + +This is a quick summary from reading `the Django documentation +`_. + +Request +------- + +``encoding``: + Is ``req.charset`` + +``REQUEST``: + Is ``req.params`` + +``FILES``: + File uploads are ``cgi.FieldStorage`` objects directly in + ``res.POST`` + +``META``: + Is ``req.environ`` + +``user``: + No equivalent (too connected to application model for WebOb). + There is ``req.remote_user``, which is only ever a string. + +``session``: + No equivalent + +``raw_post_data``: + Available with ``req.body`` + +``__getitem__(key)``: + You have to use ``req.params`` + +``is_secure()``: + No equivalent; you could use ``req.scheme == 'https'``. + +QueryDict +--------- + +QueryDict is the way Django represents the multi-key dictionary-like +objects that are request variables (query string and POST body +variables). The equivalent in WebOb is MultiDict. + +Mutability: + WebOb dictionaries are sometimes mutable (req.GET is, + req.params is not) + +Ordering: + I believe Django does not order the keys fully; MultiDict is a + full ordering. Methods that iterate over the parameters iterate + over keys in their order in the original request. + +``keys()``, ``items()``, ``values()`` (plus ``iter*``): + These return all values in MultiDict, but only the last value for + a QueryDict. That is, given ``a=1&a=2`` with MultiDict + ``d.items()`` returns ``[('a', '1'), ('a', '2')]``, but QueryDict + returns ``[('a', '1')]`` + +``getlist(key)``: + Available as ``d.getall(key)`` + +``setlist(key)``: + No direct equivalent + +``appendlist(key, value)``: + Available as ``d.add(key, value)`` + +``setlistdefault(key, default_list)``: + No direct equivalent + +``lists()``: + Is ``d.dict_of_lists()`` + +The MultiDict object has a ``d.getone(key)`` method, that raises +KeyError if there is not exactly one key. There is a method +``d.mixed()`` which returns a version where values are lists *if* +there are multiple values for a list. This is similar to how many +cgi-based request forms are represented. + +Response +-------- + +Constructor: + Totally different. The WebOb Response object should probably be + subclassed for direct application use; in WebOb it does not + *prefer* HTML or anything normal web application conventions + +dictionary-like: + The Django response object is somewhat dictionary-like, setting + headers. The equivalent dictionary-like object is + ``res.headers``. In WebOb this is a MultiDict. + +``has_header(header)``: + Use ``header in res.headers`` + +``write(content)``: + As ``res.body_file.write(content)`` + +``flush()``, ``tell()``: + Not available + +``content``: + Use ``res.body`` for the ``str`` value, ``res.unicode_body`` for + the ``unicode`` value + +Response Subclasses +------------------- + +These are generally like ``webob.exc`` objects. +``HttpResponseNotModified`` is ``HTTPNotModified``; this naming +translation generally works. + +CherryPy/TurboGears +=================== + +The `CherryPy request object +`_ is also used by +TurboGears 1.x. + +Request +------- + +``app``: + No equivalent + +``base``: + ``req.application_url`` + +``close()``: + No equivalent + +``closed``: + No equivalent + +``config``: + No equivalent + +``cookie``: + A ``SimpleCookie`` object in CherryPy; a dictionary in WebOb + (``SimpleCookie`` can represent cookie parameters, but cookie + parameters are only sent with responses not requests) + +``dispatch``: + No equivalent (this is the object dispatcher in CherryPy). + +``error_page``, ``error_response``, ``handle_error``: + No equivalent + +``get_resource()``: + Similar to ``req.get_response(app)`` + +``handler``: + No equivalent + +``headers``, ``header_list``: + The WSGI environment represents headers as a dictionary, available + through ``req.headers`` (no list form is available in the request). + +``hooks``: + No equivalent + +``local``: + No equivalent + +``methods_with_bodies``: + This represents methods where CherryPy will automatically try to + read the request body. WebOb lazily reads POST requests with the + correct content type, and no other bodies. + +``namespaces``: + No equivalent + +``protocol``: + As ``req.environ['SERVER_PROTOCOL']`` + +``query_string``: + As ``req.query_string`` + +``remote``: + ``remote.ip`` is like ``req.remote_addr``. ``remote.port`` is not + available. ``remote.name`` is in + ``req.environ.get('REMOTE_HOST')`` + +``request_line``: + No equivalent + +``respond()``: + A method that is somewhat similar to ``req.get_response()``. + +``rfile``: + ``req.body_file`` + +``run``: + No equivalent + +``server_protocol``: + As ``req.environ['SERVER_PROTOCOL']`` + +``show_tracebacks``: + No equivalent + +``throw_errors``: + No equivalent + +``throws``: + No equivalent + +``toolmaps``: + No equivalent + +``wsgi_environ``: + As ``req.environ`` + +Response +-------- + +From information `from the wiki +`_. + +``body``: + This is an iterable in CherryPy, a string in WebOb; + ``res.app_iter`` gives an iterable in WebOb. + +``check_timeout``: + No equivalent + +``collapse_body()``: + This turns a stream/iterator body into a single string. Accessing + ``res.body`` will do this automatically. + +``cookie``: + Accessible through ``res.set_cookie(...)``, ``res.delete_cookie``, + ``res.unset_cookie()`` + +``finalize()``: + No equivalent + +``header_list``: + In ``res.headerlist`` + +``stream``: + This can make CherryPy stream the response body out directory. + There is direct no equivalent; you can use a dynamically generated + iterator to do something similar. + +``time``: + No equivalent + +``timed_out``: + No equivalent + +Yaro +==== + +`Yaro `_ is a small wrapper around +the WSGI environment, much like WebOb in scope. + +The WebOb objects have many more methods and attributes. The Yaro +Response object is a much smaller subset of WebOb's Response. + +Request +------- + +``query``: + As ``req.GET`` + +``form``: + As ``req.POST`` + +``cookie``: + A ``SimpleCookie`` object in Yaro; a dictionary in WebOb + (``SimpleCookie`` can represent cookie parameters, but cookie + parameters are only sent with responses not requests) + +``uri``: + Returns a URI object, no equivalent (only string URIs available). + +``redirect``: + Not available (response-related). ``webob.exc.HTTPFound()`` can + be useful here. + +``forward(yaroapp)``, ``wsgi_forward(wsgiapp)``: + Available with ``req.get_response(app)`` and + ``req.call_application(app)``. In both cases it is a WSGI + application in WebOb, there is no special kind of communication; + ``req.call_application()`` just returns a ``webob.Response`` object. + +``res``: + The request object in WebOb *may* have a ``req.response`` + attribute. + +Werkzeug +======== + +Probably not that many people know about this library, which is a +offshoot of `Pocoo `_, and used to go by another +name (Columbrid?) This library is based around WSGI, similar to Paste +and Yaro. + +This is take from the `wrapper documentation +`_. + +Request +------- + +path: + As ``req.path_info`` +args: + As ``req.GET`` +form: + As ``req.POST`` +values: + As ``req.params`` +files: + In ``req.POST`` (as FieldStorage objects) +data: + In ``req.body_file`` + +Response +-------- + +response: + In ``res.body`` (settable as ``res.body`` or ``res.app_iter``) +status: + In ``res.status_int`` +mimetype: + In ``res.content_type`` +write(data): + With ``res.body_file.write(data)`` + +Zope 3 +====== + +From the Zope 3 interfaces for the `Request +`_ +and `Response +`_. + +Request +------- + +``locale``, ``setupLocale()``: + This is not fully calculated, but information is available in + ``req.accept_languages``. + +``principal``, ``setPrincipal(principal)``: + ``req.remote_user`` gives the username, but there is no standard + place for a user *object*. + +``publication``, ``setPublication()``, + These are associated with the object publishing system in Zope. + This kind of publishing system is outside the scope of WebOb. + +``traverse(object)``, ``getTraversalStack()``, ``setTraversalStack()``: + These all relate to traversal, which is part of the publishing + system. + +``processInputs()``, ``setPathSuffix(steps)``: + Also associated with traversal and preparing the request. + +``environment``: + In ``req.environ`` + +``bodyStream``: + In ``req.body_file`` + +``interaction``: + This is the security context for the request; all the possible + participants or principals in the request. There's no + equivalent. + +``annotations``: + Extra information associated with the request. This would + generally go in custom keys of ``req.environ``, or if you set + attributes those attributes are stored in + ``req.environ['webob.adhoc_attrs']``. + +``debug``: + There is no standard debug flag for WebOb. + +``__getitem__(key)``, ``get(key)``, etc: + These treat the request like a dictionary, which WebOb does not + do. They seem to take values from the environment, not + parameters. Also on the Zope request object is ``items()``, + ``__contains__(key)``, ``__iter__()``, ``keys()``, ``__len__()``, + ``values()``. + +``getPositionalArguments()``: + I'm not sure what the equivalent would be, as there are no + positional arguments during instantiation (it doesn't fit into + WSGI). Maybe ``wsgiorg.urlvars``? + +``retry()``, ``supportsRetry()``: + Creates a new request that can be used to retry a request. + Similar to ``req.copy()``. + +``close()``, ``hold(obj)``: + This closes resources associated with the request, including any + "held" objects. There's nothing similar. + +Response +-------- + +``authUser``: + Not sure what this is or does. + +``reset()``: + No direct equivalent; you'd have to do ``res.headers = []; + res.body = ''; res.status = 200`` + +``setCookie(name, value, **kw)``: + Is ``res.set_cookie(...)``. + +``getCookie(name)``: + No equivalent. Hm. + +``expireCookie(name)``: + Is ``res.delete_cookie(name)``. + +``appendToCookie(name, value)``: + This appends the value to any existing cookie (separating values + with a colon). WebOb does not do this. + +``setStatus(status)``: + Availble by setting ``res.status`` (can be set to an integer or a + string of "code reason"). + +``getHeader(name, default=None)``: + Is ``res.headers.get(name)``. + +``getStatus()``: + Is ``res.status_int`` (or ``res.status`` to include reason) + +``addHeader(name, value)``: + Is ``res.headers.add(name, value)`` (in Zope and WebOb, this does + not clobber any previous value). + +``getHeaders()``: + Is ``res.headerlist``. + +``setHeader(name, value)``: + Is ``res.headers[name] = value``. + +``getStatusString()``: + Is ``res.status``. + +``consumeBody()``: + This consumes any non-string body to turn the body into a single + string. Any access to ``res.body`` will do this (e.g., when you + have set the ``res.app_iter``). + +``internalError()``: + This is available with ``webob.exc.HTTP*()``. + +``handleException(exc_info)``: + This is provided with a tool like ``paste.exceptions``. + +``consumeBodyIter()``: + This returns the iterable for the body, even if the body was a + string. Anytime you access ``res.app_iter`` you will get an + iterable. ``res.body`` and ``res.app_iter`` can be interchanged + and accessed as many times as you want, unlike the Zope + equivalents. + +``setResult(result)``: + You can achieve the same thing through ``res.body = result``, or + ``res.app_iter = result``. ``res.body`` accepts None, a unicode + string (*if* you have set a charset) or a normal string. + ``res.app_iter`` only accepts None and an interable. You can't + update all of a response with one call. + + Like in Zope, WebOb updates Content-Length. Unlike Zope, it does + not automatically calculate a charset. + + +mod_python +========== + +Some key attributes from the `mod_python +`_ +request object. + +Request +------- + +``req.uri``: + In ``req.path``. + +``req.user``: + In ``req.remote_user``. + +``req.get_remote_host()``: + In ``req.environ['REMOTE_ADDR']`` or ``req.remote_addr``. + +``req.headers_in.get('referer')``: + In ``req.headers.get('referer')`` or ``req.referer`` (same pattern + for other request headers, presumably). + +Response +-------- + +``util.redirect`` or ``req.status = apache.HTTP_MOVED_TEMPORARILY``: + +.. code-block:: + + from webob.exc import HTTPMovedTemporarily() + exc = HTTPMovedTemporarily(location=url) + return exc(environ, start_response) + +``req.content_type = "application/x-csv"`` and +``req.headers_out.add('Content-Disposition', 'attachment;filename=somefile.csv'): + +.. code-block:: + + res = req.ResponseClass() + res.content_type = 'application/x-csv' + res.headers.add('Content-Disposition', 'attachment;filename=somefile.csv') + return res(environ, start_response)