{{ super() }}
{% endblock %}
Paste-2.0.3/docs/community/ 0000755 0000766 0000024 00000000000 12667667331 015774 5 ustar marca staff 0000000 0000000 Paste-2.0.3/docs/community/index.txt 0000644 0000766 0000024 00000000651 12516255245 017634 0 ustar marca staff 0000000 0000000 Community
=========
Much of the communication goes on in the `mailing lists
`_; see that page for information on the lists.
For live IRC discussion, try the ``#pythonpaste`` channel on `Freenode
`_.
If you find bugs in the code or documentation, please `submit a ticket
`_. You can also `view tickets
`_.
Paste-2.0.3/docs/community/mailing-list.txt 0000644 0000766 0000024 00000001145 12516255245 021115 0 ustar marca staff 0000000 0000000 Mailing Lists
=============
General discussion and questions should go to:
`paste-users@googlegroups.org `_:
New posts are `on Google Groups `_ `old posts are in their own archive `_
More abstract discussion of Python web programming should go to:
`web-sig@python.org `_:
`Subscribe `__,
`Archives `__
Paste-2.0.3/docs/community/repository.txt 0000644 0000766 0000024 00000000344 12516255245 020743 0 ustar marca staff 0000000 0000000 Repository
==========
Paste is kept in a Mercurial (hg) repository at
http://bitbucket.org/ianb/paste
If you are using a command-line Mercurial client, you can check
it out like::
hg clone http://bitbucket.org/ianb/paste
Paste-2.0.3/docs/conf.py 0000644 0000766 0000024 00000007756 12516255245 015254 0 ustar marca staff 0000000 0000000 # -*- coding: utf-8 -*-
#
# Paste documentation build configuration file, created by
# sphinx-quickstart on Tue Apr 22 22:08:49 2008.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# All configuration values have a default value; values that are commented out
# serve to show the default value.
import sys
# If your extensions are in another directory, add it here.
#sys.path.append('some/directory')
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.txt'
# The master toctree document.
master_doc = 'index'
# General substitutions.
project = 'Paste'
copyright = '2008, Ian Bicking'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
#
# The short X.Y version.
version = '1.7'
# The full version, including alpha/beta/rc tags.
release = '1.7.5.1'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
unused_docs = ['include/contact.txt', 'include/reference_header.txt']
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Content template for the index page.
#html_index = ''
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If true, the reST sources are included in the HTML build as _sources/.
#html_copy_source = True
# Output file base name for HTML help builder.
htmlhelp_basename = 'Pastedoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
#latex_documents = []
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
Paste-2.0.3/docs/default.css 0000644 0000766 0000024 00000013544 12516255245 016103 0 ustar marca staff 0000000 0000000 /*
:Author: David Goodger, Ian Bicking
:Contact: ianb@colorstudy.com
:date: $Date: 2003/11/01 20:35:45 $
:version: $Revision: 1.3 $
:copyright: This stylesheet has been placed in the public domain.
A modification of the default cascading style sheet (v.1.3) for the
HTML output of Docutils.
*/
body {
font-family: Arial, sans-serif;
background-color: #fff;
}
em, i {
/* Typically serif fonts have much nicer italics */
font-family: Times New Roman, Times, serif;
}
li {
list-style-type: circle;
}
a.target {
color: blue;
}
a.toc-backref {
text-decoration: none;
color: black;
}
a.toc-backref:hover {
background-color: inherit;
}
a:hover {
background-color: #ccc;
}
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6:hover {
background-color: inherit;
}
cite {
font-style: normal;
font-family: monospace;
font-weight: bold;
}
dd {
margin-bottom: 0.5em;
}
div.abstract {
margin: 2em 5em;
}
div.abstract p.topic-title {
font-weight: bold;
text-align: center;
}
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
background-color: #ccc;
width: 40%;
border: medium outset;
padding: 3px;
float: right
}
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: #c00;
font-weight: bold;
font-family: sans-serif;
text-align: center;
background-color: #999;
display: block;
margin: 0;
}
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold;
font-family: sans-serif;
text-align: center;
background-color: #999;
display: block;
margin: 0;
}
div.dedication {
margin: 2em 5em;
text-align: center;
font-style: italic;
}
div.dedication p.topic-title {
font-weight: bold;
font-style: normal;
}
div.figure {
margin-left: 2em;
}
div.footer, div.header {
font-size: smaller;
}
div.system-messages {
margin: 5em;
}
div.system-messages h1 {
color: red;
}
div.system-message {
border: medium outset;
padding: 1em;
}
div.system-message p.system-message-title {
color: red;
font-weight: bold;
}
div.topic {
margin: 2em;
}
h1, h2, h3, h4, h5, h6 {
font-family: Helvetica, Arial, sans-serif;
border: thin solid black;
/* This makes the borders rounded on Mozilla, which pleases me */
-moz-border-radius: 8px;
padding: 4px;
}
h1 {
background-color: #449;
color: #fff;
border: medium solid black;
}
h1 a.toc-backref, h2 a.toc-backref {
color: #fff;
}
h2 {
background-color: #666;
color: #fff;
border: medium solid black;
}
h3, h4, h5, h6 {
background-color: #ccc;
color: #000;
}
h3 a.toc-backref, h4 a.toc-backref, h5 a.toc-backref,
h6 a.toc-backref {
color: #000;
}
h1.title {
text-align: center;
background-color: #449;
color: #fff;
border: thick solid black;
-moz-border-radius: 20px;
}
h2.subtitle {
text-align: center;
}
hr {
width: 75%;
}
ol.simple, ul.simple {
margin-bottom: 1em;
}
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
p.caption {
font-style: italic;
}
p.credits {
font-style: italic;
font-size: smaller;
}
p.first {
margin-top: 0;
}
p.label {
white-space: nowrap;
}
p.topic-title {
font-weight: bold;
}
pre.address {
margin-bottom: 0;
margin-top: 0;
font-family: serif;
font-size: 100%;
}
pre.line-block {
font-family: serif;
font-size: 100%;
}
pre.literal-block, pre.doctest-block {
margin-left: 2em;
margin-right: 2em;
background-color: #eee;
border: thin black solid;
padding: 5px;
}
span.classifier {
font-family: sans-serif;
font-style: oblique;
}
span.classifier-delimiter {
font-family: sans-serif;
font-weight: bold;
}
span.interpreted {
font-family: sans-serif;
}
span.option-argument {
font-style: italic;
}
span.pre {
white-space: pre;
}
span.problematic {
color: red;
}
table {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
table.citation {
border-left: solid thin gray;
padding-left: 0.5ex
}
table.docinfo {
margin: 2em 4em;
}
table.footnote {
border-left: solid thin black;
padding-left: 0.5ex;
}
td, th {
padding-left: 0.5em;
padding-right: 0.5em;
vertical-align: top;
}
td > p:first-child, th > p:first-child {
margin-top: 0em;
}
th.docinfo-name, th.field-name {
font-weight: bold;
text-align: left;
white-space: nowrap;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100%;
}
code, tt {
color: #006;
}
ul.auto-toc {
list-style-type: none;
}
/*****************************************
* Doctest embedded examples
*****************************************/
span.doctest-url {
background-color: #eee;
border-top: 2px outset #666;
border-left: 2px outset #666;
border-right: 2px outset #666;
padding: 0.25em;
}
div.doctest-example {
border: outset 5px #666;
background-color: #eee;
font-family: default;
padding: 0.5em;
}
div.doctest-example h1 {
background-color: inherit;
border: none;
color: inherit;
font-family: default;
}
div.doctest-example tt {
color: inherit;
}
div.doctest-status {
background-color: #060;
color: #fff;
}
span.doctest-header {
background-color: #ccc;
font-family: monospace;
}
pre.doctest-errors {
border: none;
background-color: #333;
color: #600;
}
div.source-code {
background-color: #000;
border: inset #999 3px;
overflow: auto;
}
pre.source-code {
background-color: #000;
border: inset #999 3px;
overflow: auto;
font-family: monospace;
color: #fff;
}
span.source-filename {
background-color: #000;
border-top: 2px outset #999;
border-left: 2px outset #999;
border-right: 2px outset #999;
padding: 0.25em;
color: #fff
}
Paste-2.0.3/docs/developer-features.txt 0000644 0000766 0000024 00000010624 12516255245 020303 0 ustar marca staff 0000000 0000000 Features
========
Testing
-------
* A fixture for testing WSGI applications conveniently and in-process,
in :class:`paste.fixture.TestApp`
* A fixture for testing command-line applications, also in
:class:`paste.fixture.TestFileEnvironment`
* Check components for WSGI-compliance in :mod:`paste.lint`
* Check filesystem changes, with :mod:`paste.debug.fsdiff`
Server
------
* A threaded HTTP server in :mod:`paste.httpserver`
* A tool for seeing and killing errant threads in the HTTP server, in
:mod:`paste.debug.watchthreads`
Dispatching
-----------
* Chain and cascade WSGI applications (returning the first non-error
response) in :mod:`paste.cascade`
* Dispatch to several WSGI applications based on URL prefixes, in
:mod:`paste.urlmap`
* Allow applications to make subrequests and forward requests
internally, in :mod:`paste.recursive`
* Redirect error pages (e.g., 404 Not Found) to custom error pages, in
:mod:`paste.errordocument`.
Web Application
---------------
* Easily deal with incoming requests and sending a response in
:mod:`paste.wsgiwrappers`
* Work directly with the WSGI environment in :mod:`paste.request`
* Run CGI programs as WSGI applications in :mod:`paste.cgiapp`
* Traverse files and load WSGI applications from ``.py`` files (or
static files), in :mod:`paste.urlparser`
* Serve static directories of files, also in :mod:`paste.urlparser`; also
serve using the Setuptools ``pkg_resources`` resource API.
* Proxy to other servers, treating external HTTP servers as WSGI
applications, in :mod:`paste.proxy`.
* Serve files (with support for ``If-Modified-Since``, etc) in
:mod:`paste.fileapp`
Tools
-----
* Catch HTTP-related exceptions (e.g., ``HTTPNotFound``) and turn them
into proper responses in :mod:`paste.httpexceptions`
* Manage HTTP header fields with :mod:`paste.httpheaders`
* Handle authentication/identification of requests in :mod:`paste.auth`
* Create sessions in :mod:`paste.session` and :mod:`paste.flup_session`
* Gzip responses in :mod:`paste.gzipper`
* A wide variety of routines for manipulating WSGI requests and
producing responses, in :mod:`paste.request`, :mod:`paste.response` and
:mod:`paste.wsgilib`.
* Create Apache-style logs in :mod:`paste.translogger`
* Handy request and response wrappers in :mod:`paste.wsgiwrappers`
* Handling of request-local module globals sanely in :mod:`paste.registry`
Authentication
--------------
* Authentication using cookies in :mod:`paste.auth.cookie` and
:mod:`paste.auth.auth_tkt`; login form in :mod:`paste.auth.form`
* Authentication using `OpenID `_ in
:mod:`paste.auth.open_id`, using `CAS
`_ in :mod:`paste.auth.cas`
* HTTP authentication in :mod:`paste.auth.basic` and
:mod:`paste.auth.digest`
* Dispatch to different authentication methods based on User-Agent, in
:mod:`paste.auth.multi`
* Grant roles based on IP addresses, in :mod:`paste.auth.grantip`
Debugging Filters
-----------------
* Catch (optionally email) errors with extended tracebacks (using
Zope/ZPT conventions) in :mod:`paste.exceptions`
* During debugging, show tracebacks with information about each stack
frame, including an interactive prompt that runs in the individual
stack frames, in :mod:`paste.evalexception`.
* Catch errors presenting a `cgitb
`_-based
output, in :mod:`paste.cgitb_catcher`.
* Profile each request and append profiling information to the HTML,
in :mod:`paste.debug.profile`
* Capture ``print`` output and present it in the browser for
debugging, in :mod:`paste.debug.prints`
* Validate all HTML output from applications using the `WDG Validator
`_, appending any errors
or warnings to the page, in :mod:`paste.debug.wdg_validator`
Other Tools
-----------
* A file monitor to allow restarting the server when files have been
updated (for automatic restarting when editing code) in
:mod:`paste.reloader`
* A class for generating and traversing URLs, and creating associated
HTML code, in :mod:`paste.url`
* A small templating language (for internal use) in
:mod:`paste.util.template`
* A class to help with loops in templates, in :mod:`paste.util.looper`
* Import modules and objects given a string, in
:mod:`paste.util.import_string`
* Ordered dictionary that can have multiple values with the same key,
in :mod:`paste.util.multidict`
Paste-2.0.3/docs/DeveloperGuidelines.txt 0000644 0000766 0000024 00000011020 12516255245 020427 0 ustar marca staff 0000000 0000000 ++++++++++++++++++++++++++++
Python Paste Developer Guide
++++++++++++++++++++++++++++
Hi. Welcome to Paste. I hope you enjoy your stay here.
I hope to bring together multiple efforts here, for Paste to support
multiple frameworks and directions, while presenting a fairly
integrated frontend to users. How to do that? That's an open
question, and this code is in some ways an exploration.
There's some basic principles:
* Keep stuff decoupled.
* Must be testable. Of course tested is even better than testable.
* Use WSGI standards for communication between decoupled libraries.
* When possible, use HTTP semantics for communicating between
libraries (e.g., indicate cachability using the appropriate HTTP
headers).
* When possible, use WSGI as a wrapper around web-neutral libraries.
For instance, the configuration is a simple library, but the WSGI
middleware that puts the configuration in place is really really
simple. If it could be used outside of a web context, then having
both a library and middleware form is good.
* Entry into frameworks should be easy, but exit should also be easy.
Heterogeneous frameworks and applications are the ambition. But we
have to get some messiness into Paste before we can try to resolve
that messiness.
* When all is said and done, users should be able to ignore much of
what we've done and focus on writing their applications, and Stuff
Just Works. Documentation is good; stuff that works without user
intervention is better.
Developer Info
==============
Mostly, if there's a problem we can discuss it and work it out, no one
is going to bite your head off for committing something.
* Framework-like things should go in subpackages, or perhaps in
separate distributions entirely (Paste WebKit and Wareweb were
extracted for this reason).
* Integrating external servers and frameworks is also interesting, but
it's best to introduce that as a requirement instead of including
the work here. Paste Script contains several wrappers for external
projects (servers in particular).
* Tests are good. We use py.test_, because it is simple. I want to
use doctests too, but the infrastructure isn't really there now --
but please feel free to use those too. ``unittest`` is kind of
annoying, and py.test is both more powerful and easier to write for.
Tests should go in the ``tests/`` directory. ``paste.fixture``
contains some convenience functions for testing WSGI applications
and middleware. Pay particular attention to ``TestApp``.
.. _py.test: http://codespeak.net/py/current/doc/test.html
* If you move something around that someone may be using, keep their
imports working and introduce a warning, like::
def backward_compat_function(*args, **kw):
import warnings
# Deprecated on 2005 Mar 5
warnings.warn('Moved to foo.function', DeprecationWarning, 2)
return foo.function(*args, **kw)
* If something is really experimental, put it in your home directory,
or make a branch in your home directory. You can make a home
directory for yourself, in ``http://svn.w4py.org/home/username``.
* Not everything in the repository or even in the trunk will
necessarily go into the release. The release should contain stuff
that is tested, documented, and useful. Each module or feature also
needs a champion -- someone who will stand by the code, answer
questions, etc. It doesn't have to be the original developer, but
there has to be *someone*. So when a release is cut, if some
modules don't fulfill that they may be left out.
* Try to keep to the `Style Guidelines`_. But if you are bringing in
outside work, don't stress out too much about it. Still, if you
have a choice, follow that. Those guidelines are meant to represent
conventional Python style guides, there's nothing out of the normal
there.
.. _Style Guidelines: StyleGuide.html
* Write your docstrings in `restructured text
`_. As time goes on, I
want to rely on docstrings more for documentation, with shorter
narrative documentation pointing into the documentation generated
from docstrings.
The generation is done with `Pudge `_.
To try generating the documentation, this should work::
$ easy_install svn://lesscode.org/buildutils/trunk \
svn://lesscode.org/pudge/trunk
$ cd Paste
$ python setup.py pudge
This will install Pudge and `buildutils
`_, and then generate the
documentation into ``Paste/docs/html/``.
Paste-2.0.3/docs/do-it-yourself-framework.txt 0000644 0000766 0000024 00000045501 12516255245 021361 0 ustar marca staff 0000000 0000000 A Do-It-Yourself Framework
++++++++++++++++++++++++++
:author: Ian Bicking
:revision: $Rev$
:date: $LastChangedDate$
This tutorial has been translated `into Portuguese
`_.
A newer version of this article is available `using WebOb
`_.
.. contents::
.. comments:
Explain SCRIPT_NAME/PATH_INFO better
Introduction and Audience
=========================
This short tutorial is meant to teach you a little about WSGI, and as
an example a bit about the architecture that Paste has enabled and
encourages.
This isn't an introduction to all the parts of Paste -- in fact, we'll
only use a few, and explain each part. This isn't to encourage
everyone to go off and make their own framework (though honestly I
wouldn't mind). The goal is that when you have finished reading this
you feel more comfortable with some of the frameworks built using this
architecture, and a little more secure that you will understand the
internals if you look under the hood.
What is WSGI?
=============
At its simplest WSGI is an interface between web servers and web
applications. We'll explain the mechanics of WSGI below, but a higher
level view is to say that WSGI lets code pass around web requests in a
fairly formal way. But there's more! WSGI is more than just HTTP.
It might seem like it is just *barely* more than HTTP, but that little
bit is important:
* You pass around a CGI-like environment, which means data like
``REMOTE_USER`` (the logged-in username) can be securely passed
about.
* A CGI-like environment can be passed around with more context --
specifically instead of just one path you two: ``SCRIPT_NAME`` (how
we got here) and ``PATH_INFO`` (what we have left).
* You can -- and often should -- put your own extensions into the WSGI
environment. This allows for callbacks, extra information,
arbitrary Python objects, or whatever you want. These are things
you can't put in custom HTTP headers.
This means that WSGI can be used not just between a web server an an
application, but can be used at all levels for communication. This
allows web applications to become more like libraries -- well
encapsulated and reusable, but still with rich reusable functionality.
Writing a WSGI Application
==========================
The first part is about how to use `WSGI
`_ at its most basic. You
can read the spec, but I'll do a very brief summary:
* You will be writing a *WSGI application*. That's an object that
responds to requests. An application is just a callable object
(like a function) that takes two arguments: ``environ`` and
``start_response``.
* The environment looks a lot like a CGI environment, with keys like
``REQUEST_METHOD``, ``HTTP_HOST``, etc.
* The environment also has some special keys like ``wsgi.input`` (the
input stream, like the body of a POST request).
* ``start_response`` is a function that starts the response -- you
give the status and headers here.
* Lastly the application returns an iterator with the body response
(commonly this is just a list of strings, or just a list containing
one string that is the entire body.)
So, here's a simple application::
def app(environ, start_response):
start_response('200 OK', [('content-type', 'text/html')])
return ['Hello world!']
Well... that's unsatisfying. Sure, you can imagine what it does, but
you can't exactly point your web browser at it.
There's other cleaner ways to do this, but this tutorial isn't about
*clean* it's about *easy-to-understand*. So just add this to the
bottom of your file::
if __name__ == '__main__':
from paste import httpserver
httpserver.serve(app, host='127.0.0.1', port='8080')
Now visit http://localhost:8080 and you should see your new app.
If you want to understand how a WSGI server works, I'd recommend
looking at the `CGI WSGI server
`_
in the WSGI spec.
An Interactive App
------------------
That last app wasn't very interesting. Let's at least make it
interactive. To do that we'll give a form, and then parse the form
fields::
from paste.request import parse_formvars
def app(environ, start_response):
fields = parse_formvars(environ)
if environ['REQUEST_METHOD'] == 'POST':
start_response('200 OK', [('content-type', 'text/html')])
return ['Hello, ', fields['name'], '!']
else:
start_response('200 OK', [('content-type', 'text/html')])
return ['']
The ``parse_formvars`` function just takes the WSGI environment and
calls the `cgi `_
module (the ``FieldStorage`` class) and turns that into a MultiDict.
Now For a Framework
===================
Now, this probably feels a bit crude. After all, we're testing for
things like REQUEST_METHOD to handle more than one thing, and it's
unclear how you can have more than one page.
We want to build a framework, which is just a kind of generic
application. In this tutorial we'll implement an *object publisher*,
which is something you may have seen in Zope, Quixote, or CherryPy.
Object Publishing
-----------------
In a typical Python object publisher you translate ``/`` to ``.``. So
``/articles/view?id=5`` turns into ``root.articles.view(id=5)``. We
have to start with some root object, of course, which we'll pass in...
::
class ObjectPublisher(object):
def __init__(self, root):
self.root = root
def __call__(self, environ, start_response):
...
app = ObjectPublisher(my_root_object)
We override ``__call__`` to make instances of ``ObjectPublisher``
callable objects, just like a function, and just like WSGI
applications. Now all we have to do is translate that ``environ``
into the thing we are publishing, then call that thing, then turn the
response into what WSGI wants.
The Path
--------
WSGI puts the requested path into two variables: ``SCRIPT_NAME`` and
``PATH_INFO``. ``SCRIPT_NAME`` is everything that was used up
*getting here*. ``PATH_INFO`` is everything left over -- it's
the part the framework should be using to find the object. If you put
the two back together, you get the full path used to get to where we
are right now; this is very useful for generating correct URLs, and
we'll make sure we preserve this.
So here's how we might implement ``__call__``::
def __call__(self, environ, start_response):
fields = parse_formvars(environ)
obj = self.find_object(self.root, environ)
response_body = obj(**fields.mixed())
start_response('200 OK', [('content-type', 'text/html')])
return [response_body]
def find_object(self, obj, environ):
path_info = environ.get('PATH_INFO', '')
if not path_info or path_info == '/':
# We've arrived!
return obj
# PATH_INFO always starts with a /, so we'll get rid of it:
path_info = path_info.lstrip('/')
# Then split the path into the "next" chunk, and everything
# after it ("rest"):
parts = path_info.split('/', 1)
next = parts[0]
if len(parts) == 1:
rest = ''
else:
rest = '/' + parts[1]
# Hide private methods/attributes:
assert not next.startswith('_')
# Now we get the attribute; getattr(a, 'b') is equivalent
# to a.b...
next_obj = getattr(obj, next)
# Now fix up SCRIPT_NAME and PATH_INFO...
environ['SCRIPT_NAME'] += '/' + next
environ['PATH_INFO'] = rest
# and now parse the remaining part of the URL...
return self.find_object(next_obj, environ)
And that's it, we've got a framework.
Taking It For a Ride
--------------------
Now, let's write a little application. Put that ``ObjectPublisher``
class into a module ``objectpub``::
from objectpub import ObjectPublisher
class Root(object):
# The "index" method:
def __call__(self):
return '''
'''
def welcome(self, name):
return 'Hello %s!' % name
app = ObjectPublisher(Root())
if __name__ == '__main__':
from paste import httpserver
httpserver.serve(app, host='127.0.0.1', port='8080')
Alright, done! Oh, wait. There's still some big missing features,
like how do you set headers? And instead of giving ``404 Not Found``
responses in some places, you'll just get an attribute error. We'll
fix those up in a later installment...
Give Me More!
-------------
You'll notice some things are missing here. Most specifically,
there's no way to set the output headers, and the information on the
request is a little slim.
::
# This is just a dictionary-like object that has case-
# insensitive keys:
from paste.response import HeaderDict
class Request(object):
def __init__(self, environ):
self.environ = environ
self.fields = parse_formvars(environ)
class Response(object):
def __init__(self):
self.headers = HeaderDict(
{'content-type': 'text/html'})
Now I'll teach you a little trick. We don't want to change the
signature of the methods. But we can't put the request and response
objects in normal global variables, because we want to be
thread-friendly, and all threads see the same global variables (even
if they are processing different requests).
But Python 2.4 introduced a concept of "thread-local values". That's
a value that just this one thread can see. This is in the
`threading.local `_
object. When you create an instance of ``local`` any attributes you
set on that object can only be seen by the thread you set them in. So
we'll attach the request and response objects here.
So, let's remind ourselves of what the ``__call__`` function looked
like::
class ObjectPublisher(object):
...
def __call__(self, environ, start_response):
fields = parse_formvars(environ)
obj = self.find_object(self.root, environ)
response_body = obj(**fields.mixed())
start_response('200 OK', [('content-type', 'text/html')])
return [response_body]
Lets's update that::
import threading
webinfo = threading.local()
class ObjectPublisher(object):
...
def __call__(self, environ, start_response):
webinfo.request = Request(environ)
webinfo.response = Response()
obj = self.find_object(self.root, environ)
response_body = obj(**dict(webinfo.request.fields))
start_response('200 OK', webinfo.response.headers.items())
return [response_body]
Now in our method we might do::
class Root:
def rss(self):
webinfo.response.headers['content-type'] = 'text/xml'
...
If we were being fancier we would do things like handle `cookies
`_ in these
objects. But we aren't going to do that now. You have a framework,
be happy!
WSGI Middleware
===============
`Middleware
`_
is where people get a little intimidated by WSGI and Paste.
What is middleware? Middleware is software that serves as an
intermediary.
So lets
write one. We'll write an authentication middleware, so that you can
keep your greeting from being seen by just anyone.
Let's use HTTP authentication, which also can mystify people a bit.
HTTP authentication is fairly simple:
* When authentication is requires, we give a ``401 Authentication
Required`` status with a ``WWW-Authenticate: Basic realm="This
Realm"`` header
* The client then sends back a header ``Authorization: Basic
encoded_info``
* The "encoded_info" is a base-64 encoded version of
``username:password``
So how does this work? Well, we're writing "middleware", which means
we'll typically pass the request on to another application. We could
change the request, or change the response, but in this case sometimes
we *won't* pass the request on (like, when we need to give that 401
response).
To give an example of a really really simple middleware, here's one
that capitalizes the response::
class Capitalizer(object):
# We generally pass in the application to be wrapped to
# the middleware constructor:
def __init__(self, wrap_app):
self.wrap_app = wrap_app
def __call__(self, environ, start_response):
# We call the application we are wrapping with the
# same arguments we get...
response_iter = self.wrap_app(environ, start_response)
# then change the response...
response_string = ''.join(response_iter)
return [response_string.upper()]
Techically this isn't quite right, because there there's two ways to
return the response body, but we're skimming bits.
`paste.wsgilib.intercept_output
`_
is a somewhat more thorough implementation of this.
.. note::
This, like a lot of parts of this (now fairly old) tutorial is
better, more thorough, and easier using `WebOb
`_. This particular example looks
like::
from webob import Request
class Capitalizer(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
req = Request(environ)
resp = req.get_response(self.app)
resp.body = resp.body.upper()
return resp(environ, start_response)
So here's some code that does something useful, authentication::
class AuthMiddleware(object):
def __init__(self, wrap_app):
self.wrap_app = wrap_app
def __call__(self, environ, start_response):
if not self.authorized(environ.get('HTTP_AUTHORIZATION')):
# Essentially self.auth_required is a WSGI application
# that only knows how to respond with 401...
return self.auth_required(environ, start_response)
# But if everything is okay, then pass everything through
# to the application we are wrapping...
return self.wrap_app(environ, start_response)
def authorized(self, auth_header):
if not auth_header:
# If they didn't give a header, they better login...
return False
# .split(None, 1) means split in two parts on whitespace:
auth_type, encoded_info = auth_header.split(None, 1)
assert auth_type.lower() == 'basic'
unencoded_info = encoded_info.decode('base64')
username, password = unencoded_info.split(':', 1)
return self.check_password(username, password)
def check_password(self, username, password):
# Not very high security authentication...
return username == password
def auth_required(self, environ, start_response):
start_response('401 Authentication Required',
[('Content-type', 'text/html'),
('WWW-Authenticate', 'Basic realm="this realm"')])
return ["""
Authentication Required
Authentication Required
If you can't get in, then stay out.
"""]
.. note::
Again, here's the same thing with WebOb::
from webob import Request, Response
class AuthMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
req = Request(environ)
if not self.authorized(req.headers['authorization']):
resp = self.auth_required(req)
else:
resp = self.app
return resp(environ, start_response)
def authorized(self, header):
if not header:
return False
auth_type, encoded = header.split(None, 1)
if not auth_type.lower() == 'basic':
return False
username, password = encoded.decode('base64').split(':', 1)
return self.check_password(username, password)
def check_password(self, username, password):
return username == password
def auth_required(self, req):
return Response(status=401, headers={'WWW-Authenticate': 'Basic realm="this realm"'},
body="""\
Authentication Required
Authentication Required
If you can't get in, then stay out.
""")
So, how do we use this?
::
app = ObjectPublisher(Root())
wrapped_app = AuthMiddleware(app)
if __name__ == '__main__':
from paste import httpserver
httpserver.serve(wrapped_app, host='127.0.0.1', port='8080')
Now you have middleware! Hurrah!
Give Me More Middleware!
------------------------
It's even easier to use other people's middleware than to make your
own, because then you don't have to program. If you've been following
along, you've probably encountered a few exceptions, and have to look
at the console to see the exception reports. Let's make that a little
easier, and show the exceptions in the browser...
::
app = ObjectPublisher(Root())
wrapped_app = AuthMiddleware(app)
from paste.exceptions.errormiddleware import ErrorMiddleware
exc_wrapped_app = ErrorMiddleware(wrapped_app)
Easy! But let's make it *more* fancy...
::
app = ObjectPublisher(Root())
wrapped_app = AuthMiddleware(app)
from paste.evalexception import EvalException
exc_wrapped_app = EvalException(wrapped_app)
So go make an error now. And hit the little +'s. And type stuff in
to the boxes.
Conclusion
==========
Now that you've created your framework and application (I'm sure it's
much nicer than the one I've given so far). You might keep writing it
(many people have so far), but even if you don't you should be able to
recognize these components in other frameworks now, and you'll have a
better understanding how they probably work under the covers.
Also check out the version of this tutorial written `using WebOb
`_. That tutorial
includes things like **testing** and **pattern-matching dispatch**
(instead of object publishing).
Paste-2.0.3/docs/download/ 0000755 0000766 0000024 00000000000 12667667331 015557 5 ustar marca staff 0000000 0000000 Paste-2.0.3/docs/download/index.txt 0000644 0000766 0000024 00000002266 12516255245 017423 0 ustar marca staff 0000000 0000000 Downloads
=========
Each of these packages is available in several formats. The source
distribution is a complete set of documentation, tests, and the source
files themselves. There are also two "Egg" files: these are files
`easy_install `_
can install directly into your ``site-packages/`` directory, and are
Python-version specific. The download files for the latest version
are always located on the Cheese Shop pages (listed below).
* `Paste `_
* `Paste Script `_
* `Paste Deploy `_
* `Paste WebKit `_
* `Wareweb `_ (deprecated, use `Pylons
`_ instead)
All the packages are available in the Mercurial repositories rooted in
http://bitbucket.org/ianb/
* http://bitbucket.org/ianb/paste
* http://bitbucket.org/ianb/pastescript
* http://bitbucket.org/ianb/pastedeploy
* https://github.com/Pylons/webob
* ... and others
Use::
hg clone http://bitbucket.org/ianb/paste
to check out a working copy of Paste.
Paste-2.0.3/docs/future.txt 0000644 0000766 0000024 00000006173 12516255245 016020 0 ustar marca staff 0000000 0000000 The Future Of Paste
===================
Introduction
------------
Paste has been under development for a while, and has lots of code in it. Too much code! The code is largely decoupled except for some core functions shared by many parts of the code. Those core functions are largely replaced in `WebOb `_, and replaced with better implementations.
The future of these pieces is to split them into independent packages, and refactor the internal Paste dependencies to rely instead on WebOb.
Already Extracted
-----------------
paste.fixture:
WebTest
ScriptTest
paste.lint:
wsgiref.validate
paste.exceptions and paste.evalexception:
WebError
paste.util.template:
Tempita
To Be Separated
---------------
paste.httpserver and paste.debug.watchthreads:
Not sure what to call this.
paste.cascade and paste.errordocuments:
Not sure; Ben has an implementation of errordocuments in ``pylons.middleware.StatusCodeRedirect``
paste.urlmap, paste.deploy.config.PrefixMiddleware:
In... some routing thing? Together with the previous package?
paste.proxy:
WSGIProxy (needs lots of cleanup though)
paste.fileapp, paste.urlparser.StaticURLParser, paste.urlparser.PkgResourcesParser:
In some new file-serving package.
paste.cgiapp, wphp.fcgi_app:
Some proxyish app... maybe WSGIProxy?
paste.translogger, paste.debug.prints, paste.util.threadedprint, wsgifilter.proxyapp.DebugHeaders:
Some... other place. Something loggy.
paste.registry, paste.config:
Not sure. Alberto Valverde expressed interest in splitting out paste.registry.
paste.cgitb_catcher:
Move to WebError? Not sure if it matters. For some reason people use this, though.
To Deprecate
------------
(In that, I won't extract these anywhere; I'm not going to do any big deletes anytime soon, though)
paste.recursive
Better to do it manually (with webob.Request.get_response)
paste.wsgiwrappers, paste.request, paste.response, paste.wsgilib, paste.httpheaders, paste.httpexceptions:
All the functionality is already in WebOb.
paste.urlparser.URLParser:
Really this is tied to paste.webkit more than anything.
paste.auth.*:
Well, these all need to be refactored, and replacements exist in AuthKit and repoze.who. Some pieces might still have utility.
paste.debug.profile:
I think repoze.profile supersedes this.
paste.debug.wdg_validator:
It could get reimplemented with more options for validators, but I'm not really that interested at the moment. The code is nothing fancy.
paste.transaction:
More general in repoze.tm
paste.url:
No one uses this
Undecided
---------
paste.debug.fsdiff:
Maybe ScriptTest?
paste.session:
It's an okay naive session system. But maybe Beaker makes it irrelevant (Beaker does seem slightly more complex to setup). But then, this can just live here indefinitely.
paste.gzipper:
I'm a little uncomfortable with this in concept. It's largely in WebOb right now, but not as middleware.
paste.reloader:
Maybe this should be moved to paste.script (i.e., paster serve)
paste.debug.debugapp, paste.script.testapp:
Alongside other debugging tools, I guess
paste.progress:
Not sure this works.
Paste-2.0.3/docs/include/ 0000755 0000766 0000024 00000000000 12667667331 015373 5 ustar marca staff 0000000 0000000 Paste-2.0.3/docs/include/contact.txt 0000644 0000766 0000024 00000000522 12516255245 017554 0 ustar marca staff 0000000 0000000 If you have questions about this document, please contact the `paste
mailing list `_
or try IRC (``#pythonpaste`` on freenode.net). If there's something that
confused you and you want to give feedback, please `submit an issue
`_.
Paste-2.0.3/docs/include/reference_header.txt 0000644 0000766 0000024 00000000102 12516255245 021361 0 ustar marca staff 0000000 0000000 Paste Reference Document
@@@@@@@@@@@@@@@@@@@@@@@@
.. contents::
Paste-2.0.3/docs/index.txt 0000644 0000766 0000024 00000003120 12516255245 015602 0 ustar marca staff 0000000 0000000 Python Paste
============
Contents:
.. toctree::
:maxdepth: 1
news
future
testing-applications
url-parsing-with-wsgi
do-it-yourself-framework
paste-httpserver-threadpool
developer-features
DeveloperGuidelines
StyleGuide
paste-httpserver-threadpool
testing-applications
url-parsing-with-wsgi
community/index.txt
community/mailing-list.txt
community/repository.txt
download/index.txt
license
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. comment:
I want to put these somewhere sometime, but no place for them now...
Python Paste -- 50% tastier than Elmer's!
Paste: making the web sticky.
Fix broken websites by applying Paste liberally.
Paste: paper over your inconsistencies.
Paste: a soft mixture of malleable consistency.
Paste: a tasty mixture to be spread on bread or crackers.
Paste: glue that won't hurt you if you eat it.
Python Paste: the web extruded into the form of a snake.
Paste: the vinegar eel.
Paste: you bring the cut.
Paste: a doughy substance from which to make metaphorical web cupcakes.
LAMP? LAMPP!
Putting the P in Wep 2.0!
Frankenweb crush tiny humans!
DSL? DSF!
Paste: Comfort for the framework-scarred
Other Components
================
* `Paste Deploy <./deploy/>`_
* `Paste Script <./script/>`_
* `WebOb `_
* `WSGI specification (PEP 333) `_
License
=======
Paste is distributed under the `MIT license
`_.
Paste-2.0.3/docs/license.txt 0000644 0000766 0000024 00000002065 12516255245 016124 0 ustar marca staff 0000000 0000000 Copyright (c) 2006-2007 Ian Bicking and Contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Paste-2.0.3/docs/modules/ 0000755 0000766 0000024 00000000000 12667667331 015420 5 ustar marca staff 0000000 0000000 Paste-2.0.3/docs/modules/auth.auth_tkt.txt 0000644 0000766 0000024 00000000470 12516255245 020733 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.auth_tkt` -- auth_tkt cookie parsing
=====================================================
.. automodule:: paste.auth.auth_tkt
Module Contents
---------------
.. autoclass:: AuthTKTMiddleware
.. autofunction:: make_auth_tkt_middleware
.. autoclass:: AuthTicket
.. autoexception:: BadTicket
Paste-2.0.3/docs/modules/auth.basic.txt 0000644 0000766 0000024 00000000421 12516255245 020165 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.basic` -- Basic HTTP authentication
====================================================
.. automodule:: paste.auth.basic
Module Contents
---------------
.. autoclass:: AuthBasicAuthenticator
.. autoclass:: AuthBasicHandler
.. autofunction:: make_basic
Paste-2.0.3/docs/modules/auth.cas.txt 0000644 0000766 0000024 00000000272 12516255245 017656 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.cas` -- CAS authentication
===========================================
.. automodule:: paste.auth.cas
Module Contents
---------------
.. autoclass:: AuthCASHandler
Paste-2.0.3/docs/modules/auth.cookie.txt 0000644 0000766 0000024 00000000472 12516255245 020363 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.cookie` -- Cookie-based authentication
=======================================================
.. automodule:: paste.auth.cookie
Module Contents
---------------
.. autoclass:: AuthCookieSigner
.. autoclass:: AuthCookieHandler
.. autoclass:: AuthCookieEnviron
.. autofunction:: make_auth_cookie
Paste-2.0.3/docs/modules/auth.digest.txt 0000644 0000766 0000024 00000000451 12516255245 020366 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.digest` -- HTTP Digest login
=============================================
.. automodule:: paste.auth.digest
Module Contents
---------------
.. autoclass:: AuthDigestAuthenticator
.. autoclass:: AuthDigestHandler
.. autofunction:: digest_password
.. autofunction:: make_digest
Paste-2.0.3/docs/modules/auth.form.txt 0000644 0000766 0000024 00000000362 12516255245 020053 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.form` -- HTML form/cookie authentication
=========================================================
.. automodule:: paste.auth.form
Module Contents
---------------
.. autoclass:: AuthFormHandler
.. autofunction:: make_form
Paste-2.0.3/docs/modules/auth.grantip.txt 0000644 0000766 0000024 00000000420 12516255245 020547 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.grantip` -- Set user and groups based on IP address
====================================================================
.. automodule:: paste.auth.grantip
Module Contents
---------------
.. autoclass:: GrantIPMiddleware
.. autofunction:: make_grantip
Paste-2.0.3/docs/modules/auth.multi.txt 0000644 0000766 0000024 00000000356 12516255245 020245 0 ustar marca staff 0000000 0000000 :mod:`paste.auth.multi` -- Authentication via one of multiple methods
=====================================================================
.. automodule:: paste.auth.multi
Module Contents
---------------
.. autoclass:: MultiHandler
Paste-2.0.3/docs/modules/cascade.txt 0000644 0000766 0000024 00000000421 12516255245 017527 0 ustar marca staff 0000000 0000000 :mod:`paste.cascade` -- send requests to multiple applications until success
============================================================================
.. automodule:: paste.cascade
Module Contents
---------------
.. autoclass:: Cascade
.. autofunction:: make_cascade
Paste-2.0.3/docs/modules/cgiapp.txt 0000644 0000766 0000024 00000000431 12516255245 017410 0 ustar marca staff 0000000 0000000 :mod:`paste.cgiapp` -- run CGI scripts as WSGI applications
===========================================================
.. automodule:: paste.cgiapp
Module Contents
---------------
.. autoclass:: CGIApplication
.. autoexception:: CGIError
.. autofunction:: make_cgi_application
Paste-2.0.3/docs/modules/cgitb_catcher.txt 0000644 0000766 0000024 00000000404 12516255245 020726 0 ustar marca staff 0000000 0000000 :mod:`paste.cgitb_catcher` -- catch exceptions using cgitb
==========================================================
.. automodule:: paste.cgitb_catcher
Module Contents
---------------
.. autoclass:: CgitbMiddleware
.. autofunction:: make_cgitb_middleware
Paste-2.0.3/docs/modules/debug.debugapp.txt 0000644 0000766 0000024 00000000430 12516255245 021020 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.debugapp` -- debug app
========================================
.. automodule:: paste.debug.debugapp
Module Contents
---------------
.. autoclass:: SimpleApplication
.. autoclass:: SlowConsumer
.. autofunction:: make_test_app
.. autofunction:: make_slow_app
Paste-2.0.3/docs/modules/debug.fsdiff.txt 0000644 0000766 0000024 00000000542 12516255245 020476 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.fsdiff` -- Show differences between directories
=================================================================
.. automodule:: paste.debug.fsdiff
Module Contents
---------------
.. autoclass:: Diff
.. autoclass:: Snapshot
.. autoclass:: File
.. autoclass:: Dir
.. autofunction:: report_expected_diffs
.. autofunction:: show_diff
Paste-2.0.3/docs/modules/debug.prints.txt 0000644 0000766 0000024 00000000317 12516255245 020554 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.prints` -- capture print output
=================================================
.. automodule:: paste.debug.prints
Module Contents
---------------
.. autoclass:: PrintDebugMiddleware
Paste-2.0.3/docs/modules/debug.profile.txt 0000644 0000766 0000024 00000000470 12516255245 020675 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.profile` -- profile applications and requests
===============================================================
.. automodule:: paste.debug.profile
Module Contents
---------------
.. autoclass:: ProfileMiddleware
.. autofunction:: make_profile_middleware
.. autofunction:: profile_decorator
Paste-2.0.3/docs/modules/debug.watchthreads.txt 0000644 0000766 0000024 00000000505 12516255245 021715 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.watchthreads` -- watch thread workers in paste.httpserver
===========================================================================
.. automodule:: paste.debug.watchthreads
Module Contents
---------------
.. autoclass:: WatchThreads
.. autofunction:: make_watch_threads
.. autofunction:: make_bad_app
Paste-2.0.3/docs/modules/debug.wdg_validate.txt 0000644 0000766 0000024 00000000363 12516255245 021670 0 ustar marca staff 0000000 0000000 :mod:`paste.debug.debugapp` -- debug app
========================================
.. automodule:: paste.debug.wdg_validate
Module Contents
---------------
.. autoclass:: WDGValidateMiddleware
.. autofunction:: make_wdg_validate_middleware
Paste-2.0.3/docs/modules/errordocument.txt 0000644 0000766 0000024 00000000440 12516255245 021035 0 ustar marca staff 0000000 0000000 :mod:`paste.errordocument` -- Do internal redirects for error responses
=======================================================================
.. automodule:: paste.errordocument
Module Contents
---------------
.. autoclass:: StatusBasedForward
.. autofunction:: make_errordocument
Paste-2.0.3/docs/modules/evalexception.txt 0000644 0000766 0000024 00000000342 12516255245 021014 0 ustar marca staff 0000000 0000000 :mod:`paste.evalexception` -- Interactive debugging for errors
==============================================================
.. automodule:: paste.evalexception
Module Contents
---------------
.. autoclass:: EvalException
Paste-2.0.3/docs/modules/exceptions.txt 0000644 0000766 0000024 00000002353 12516255245 020333 0 ustar marca staff 0000000 0000000 :mod:`paste.exceptions` -- Catch, display, and notify for exceptions
====================================================================
.. automodule:: paste.exceptions.errormiddleware
Module Contents
---------------
.. autoclass:: ErrorMiddleware
.. autofunction:: handle_exception
.. autofunction:: make_error_middleware
:mod:`paste.exceptions.collector` -- Collection information from exceptions
===========================================================================
.. automodule:: paste.exceptions.collector
Module Contents
---------------
.. autoclass:: ExceptionCollector
.. autofunction:: collect_exception
:mod:`paste.exceptions.formatter` -- Format exception information
=================================================================
.. automodule:: paste.exceptions.formatter
Module Contents
---------------
.. autoclass:: TextFormatter
.. autoclass:: HTMLFormatter
.. autofunction:: format_html
.. autofunction:: format_text
:mod:`paste.exceptions.reporter` -- Report exceptions
=====================================================
.. automodule:: paste.exceptions.reporter
Module Contents
---------------
.. autoclass:: EmailReporter
.. autoclass:: LogReporter
.. autoclass:: FileReporter
.. autoclass:: WSGIAppReporter
Paste-2.0.3/docs/modules/fileapp.txt 0000644 0000766 0000024 00000000370 12516255245 017567 0 ustar marca staff 0000000 0000000 :mod:`paste.fileapp` -- Serve files
===================================
.. automodule:: paste.fileapp
Module Contents
---------------
.. autoclass:: FileApp
.. autoclass:: DirectoryApp
.. autofunction:: DataApp
.. autofunction:: ArchiveStore
Paste-2.0.3/docs/modules/fixture.txt 0000644 0000766 0000024 00000001171 12516255245 017635 0 ustar marca staff 0000000 0000000 :mod:`paste.fixture` -- Test applications
=========================================
.. contents::
.. automodule:: paste.fixture
Module Contents
---------------
.. autoclass:: TestApp
:members:
.. autoclass:: TestRequest
Forms
-----
.. autoclass:: Form
:members:
.. autoclass:: Field
:members:
.. autoclass:: Select
.. autoclass:: Radio
.. autoclass:: Checkbox
.. autoclass:: Text
.. autoclass:: Textarea
.. autoclass:: Hidden
.. autoclass:: Submit
Script Testing
--------------
.. autoclass:: TestFileEnvironment
:members:
.. autoclass:: ProcResult
:members:
.. autoclass:: FoundFile
.. autoclass:: FoundDir
Paste-2.0.3/docs/modules/gzipper.txt 0000644 0000766 0000024 00000000342 12516255245 017626 0 ustar marca staff 0000000 0000000 :mod:`paste.gzipper` -- Gzip-compress responses
===============================================
.. automodule:: paste.gzipper
Module Contents
---------------
.. autoclass:: middleware
.. autofunction:: make_gzip_middleware
Paste-2.0.3/docs/modules/httpexceptions.txt 0000644 0000766 0000024 00000003104 12516255245 021226 0 ustar marca staff 0000000 0000000 :mod:`paste.httpexceptions` -- Easily product HTTP errors
=========================================================
.. automodule:: paste.httpexceptions
Module Contents
---------------
.. autoclass:: HTTPExceptionHandler
.. autofunction:: make_middleware
Exceptions
----------
.. autoexception:: HTTPException
.. autoexception:: HTTPError
.. autoexception:: HTTPRedirection
.. autoexception:: HTTPMultipleChoices
.. autoexception:: HTTPMovedPermanently
.. autoexception:: HTTPFound
.. autoexception:: HTTPNotModified
.. autoexception:: HTTPUseProxy
.. autoexception:: HTTPTemporaryRedirect
.. autoexception:: HTTPClientError
.. autoexception:: HTTPBadRequest
.. autoexception:: HTTPUnauthorized
.. autoexception:: HTTPPaymentRequired
.. autoexception:: HTTPForbidden
.. autoexception:: HTTPNotFound
.. autoexception:: HTTPMethodNotAllowed
.. autoexception:: HTTPNotAcceptable
.. autoexception:: HTTPProxyAuthenticationRequired
.. autoexception:: HTTPRequestTimeout
.. autoexception:: HTTPConflict
.. autoexception:: HTTPGone
.. autoexception:: HTTPLengthRequired
.. autoexception:: HTTPPreconditionFailed
.. autoexception:: HTTPRequestEntityTooLarge
.. autoexception:: HTTPRequestURITooLong
.. autoexception:: HTTPUnsupportedMediaType
.. autoexception:: HTTPRequestRangeNotSatisfiable
.. autoexception:: HTTPExpectationFailed
.. autoexception:: HTTPServerError
.. autoexception:: HTTPInternalServerError
.. autoexception:: HTTPNotImplemented
.. autoexception:: HTTPBadGateway
.. autoexception:: HTTPServiceUnavailable
.. autoexception:: HTTPGatewayTimeout
.. autoexception:: HTTPVersionNotSupported
Paste-2.0.3/docs/modules/httpheaders.txt 0000644 0000766 0000024 00000000330 12516255245 020456 0 ustar marca staff 0000000 0000000 :mod:`paste.httpheaders` -- Manipulate HTTP Headers
===================================================
.. comment:
I just don't feel like documenting the items...
.. automodule:: paste.httpheaders
:members:
Paste-2.0.3/docs/modules/httpserver.txt 0000644 0000766 0000024 00000000312 12516255245 020351 0 ustar marca staff 0000000 0000000 :mod:`paste.httpserver` -- HTTP server
======================================
.. automodule:: paste.httpserver
Module Contents
---------------
.. autofunction:: serve
.. autofunction:: server_runner
Paste-2.0.3/docs/modules/lint.txt 0000644 0000766 0000024 00000000420 12516255245 017111 0 ustar marca staff 0000000 0000000 :mod:`paste.lint` -- Check for the validity of WSGI requests and responses
==========================================================================
.. automodule:: paste.lint
Module Contents
---------------
.. autofunction:: middleware
.. autoexception:: WSGIWarning
Paste-2.0.3/docs/modules/pony.txt 0000644 0000766 0000024 00000000350 12516255245 017132 0 ustar marca staff 0000000 0000000 :mod:`paste.pony` -- Add pony power to your application
=======================================================
.. automodule:: paste.pony
Module Contents
---------------
.. autoclass:: PonyMiddleware
.. autofunction:: make_pony
Paste-2.0.3/docs/modules/progress.txt 0000644 0000766 0000024 00000000366 12516255245 020020 0 ustar marca staff 0000000 0000000 :mod:`paste.progress` -- Track progress of uploads
==================================================
.. automodule:: paste.progress
Module Contents
---------------
.. autoclass:: UploadProgressMonitor
.. autoclass:: UploadProgressReporter
Paste-2.0.3/docs/modules/proxy.txt 0000644 0000766 0000024 00000000462 12516255245 017332 0 ustar marca staff 0000000 0000000 :mod:`paste.proxy` -- Proxy WSGI requests to HTTP requests
==========================================================
.. automodule:: paste.proxy
Module Contents
---------------
.. autoclass:: Proxy
.. autofunction:: make_proxy
.. autoclass:: TransparentProxy
.. autofunction:: make_transparent_proxy
Paste-2.0.3/docs/modules/recursive.txt 0000644 0000766 0000024 00000000350 12516255245 020154 0 ustar marca staff 0000000 0000000 :mod:`paste.recursive` -- internal requests
===========================================
.. automodule:: paste.recursive
Module Contents
---------------
.. autoclass:: RecursiveMiddleware
.. autofunction:: ForwardRequestException
Paste-2.0.3/docs/modules/registry.txt 0000644 0000766 0000024 00000000564 12516255245 020024 0 ustar marca staff 0000000 0000000 :mod:`paste.registry` -- Manage thread-local request-specific objects
=====================================================================
.. automodule:: paste.registry
Module Contents
---------------
.. autoclass:: StackedObjectProxy
.. autoclass:: Registry
.. autoclass:: RegistryManager
.. autoclass:: StackedObjectRestorer
.. autofunction:: make_registry_manager
Paste-2.0.3/docs/modules/reloader.txt 0000644 0000766 0000024 00000000445 12516255245 017747 0 ustar marca staff 0000000 0000000 :mod:`paste.reloader` -- Monitor for file changes to restart the process
========================================================================
.. automodule:: paste.reloader
Module Contents
---------------
.. autofunction:: install
.. autoclass:: Monitor
.. autofunction:: watch_file
Paste-2.0.3/docs/modules/request.txt 0000644 0000766 0000024 00000000765 12516255245 017647 0 ustar marca staff 0000000 0000000 :mod:`paste.request` -- Utility functions for the WSGI environment
==================================================================
.. automodule:: paste.request
Module Contents
---------------
.. autofunction:: get_cookies
.. autofunction:: get_cookie_dict
.. autofunction:: parse_querystring
.. autofunction:: parse_formvars
.. autofunction:: construct_url
.. autofunction:: path_info_split
.. autofunction:: path_info_pop
.. autofunction:: resolve_relative_url
.. autoclass:: EnvironHeaders
Paste-2.0.3/docs/modules/response.txt 0000644 0000766 0000024 00000000541 12516255245 020005 0 ustar marca staff 0000000 0000000 :mod:`paste.response` -- Utility functions for producing responses
==================================================================
.. automodule:: paste.response
Module Contents
---------------
.. autoclass:: HeaderDict
.. autofunction:: has_header
.. autofunction:: header_value
.. autofunction:: remove_header
.. autofunction:: replace_header
Paste-2.0.3/docs/modules/session.txt 0000644 0000766 0000024 00000000363 12516255245 017634 0 ustar marca staff 0000000 0000000 :mod:`paste.session` -- Simple file-based sessions
==================================================
.. automodule:: paste.session
Module Contents
---------------
.. autoclass:: SessionMiddleware
.. autofunction:: make_session_middleware
Paste-2.0.3/docs/modules/transaction.txt 0000644 0000766 0000024 00000000434 12516255245 020475 0 ustar marca staff 0000000 0000000 :mod:`paste.transaction` -- DB-API transactions
===============================================
.. automodule:: paste.transaction
Module Contents
---------------
.. autoclass:: TransactionManagerMiddleware
.. autoclass:: ConnectionFactory
.. autofunction:: BasicTransactionHandler
Paste-2.0.3/docs/modules/translogger.txt 0000644 0000766 0000024 00000000320 12516255245 020471 0 ustar marca staff 0000000 0000000 :mod:`paste.translogger` -- Log requests
========================================
.. automodule:: paste.translogger
Module Contents
---------------
.. autoclass:: TransLogger
.. autofunction:: make_filter
Paste-2.0.3/docs/modules/url.txt 0000644 0000766 0000024 00000000271 12516255245 016751 0 ustar marca staff 0000000 0000000 :mod:`paste.url` -- URL convenience class
=========================================
.. automodule:: paste.url
Module Contents
---------------
.. autoclass:: URL
.. autoclass:: Image
Paste-2.0.3/docs/modules/urlmap.txt 0000644 0000766 0000024 00000000340 12516255245 017444 0 ustar marca staff 0000000 0000000 :mod:`paste.urlmap` -- Map URL paths
====================================
.. automodule:: paste.urlmap
Module Contents
---------------
.. autoclass:: URLMap
.. autofunction:: urlmap_factory
.. autoclass:: PathProxyURLMap
Paste-2.0.3/docs/modules/urlparser.txt 0000644 0000766 0000024 00000000610 12516255245 020163 0 ustar marca staff 0000000 0000000 :mod:`paste.urlparser` -- Handle URL paths and server static files
==================================================================
.. automodule:: paste.urlparser
Module Contents
---------------
.. autoclass:: StaticURLParser
.. autofunction:: make_static
.. autoclass:: PkgResourcesParser
.. autofunction:: make_pkg_resources
.. autoclass:: URLParser
.. autofunction:: make_url_parser
Paste-2.0.3/docs/modules/util.import_string.txt 0000644 0000766 0000024 00000000514 12516255245 022023 0 ustar marca staff 0000000 0000000 :mod:`paste.util.import_string` -- Import objects from strings
==============================================================
.. automodule:: paste.util.import_string
Module Contents
---------------
.. autofunction:: eval_import
.. autofunction:: simple_import
.. autofunction:: import_module
.. autofunction:: try_import_module
Paste-2.0.3/docs/modules/util.multidict.txt 0000644 0000766 0000024 00000000404 12516255245 021117 0 ustar marca staff 0000000 0000000 :mod:`paste.util.multidict` -- Dictionaries with multiple values
================================================================
.. automodule:: paste.util.multidict
Module Contents
---------------
.. autoclass:: MultiDict
.. autoclass:: UnicodeMultiDict
Paste-2.0.3/docs/modules/wsgilib.txt 0000644 0000766 0000024 00000001010 12516255245 017577 0 ustar marca staff 0000000 0000000 :mod:`paste.wsgilib` -- Miscellaneous WSGI utility functions
============================================================
.. automodule:: paste.wsgilib
Module Contents
---------------
.. autofunction:: add_close
.. autofunction:: add_start_close
.. autofunction:: chained_app_iters
.. autoclass:: encode_unicode_app_iter
.. autofunction:: catch_errors
.. autofunction:: catch_errors_app
.. autofunction:: raw_interactive
.. autofunction:: interactive
.. autofunction:: dump_environ
.. autofunction:: intercept_output
Paste-2.0.3/docs/modules/wsgiwrappers.txt 0000644 0000766 0000024 00000000427 12516255245 020707 0 ustar marca staff 0000000 0000000 :mod:`paste.wsgiwrappers` -- Wrapper functions for WSGI request and response
============================================================================
.. automodule:: paste.wsgiwrappers
Module Contents
---------------
.. autoclass:: WSGIRequest
.. autoclass:: WSGIResponse
Paste-2.0.3/docs/news.txt 0000644 0000766 0000024 00000112246 12667667030 015467 0 ustar marca staff 0000000 0000000 News
====
.. contents::
2.0.3
-----
* #26: Change six requirement to >=1.4.0
from [Linus Heckemann](https://bitbucket.org/sphalerite/)
https://bitbucket.org/ianb/paste/pull-requests/26/change-six-requirement-to-140/diff
* #28: Py3k fixes
from [Nils Philippsen](https://bitbucket.org/nilsph/)
https://bitbucket.org/ianb/paste/pull-requests/28/py3k-fixes/diff
* #29: paste.wsgilib.add_close: Add __next__ method to support using `add_close` objects as iterators on Python 3.
fixes https://bitbucket.org/ianb/pastedeploy/issues/18/py3-test_config_middleware-failed
from [Marc Abramowitz](https://bitbucket.org/msabramo/)
https://bitbucket.org/ianb/paste/pull-requests/29/pastewsgilibadd_close-add-__next__-method/diff
* #30: tox.ini: Add py35 to envlist
from [Marc Abramowitz](https://bitbucket.org/msabramo/)
https://bitbucket.org/ianb/paste/pull-requests/30/toxini-add-py35-to-envlist/diff
* #31: Enable testing with pypy
from [Marc Abramowitz](https://bitbucket.org/msabramo/)
https://bitbucket.org/ianb/paste/pull-requests/31/enable-testing-with-pypy/diff
* #33: tox.ini: Measure test coveraage
from [Marc Abramowitz](https://bitbucket.org/msabramo/)
https://bitbucket.org/ianb/paste/pull-requests/33/toxini-measure-test-coverage/diff
2.0.2
-----
* #22: Fix improper commas in request headers in wsgi_environ (https://bitbucket.org/ianb/paste/pull-request/22/fix-improper-commas-in-request-headers-in)
Fixes issue #4 ("WSGI environ totally borked") (https://bitbucket.org/ianb/paste/issue/4/wsgi-environ-totally-borked)
* #24: test_wsgirequest_charset: Use UTF-8 instead of iso-8859-1 (https://bitbucket.org/ianb/paste/pull-request/24/test_wsgirequest_charset-use-utf-8-instead)
Fixes issue #7 ("Python 3 test failure") (https://bitbucket.org/ianb/paste/issue/7/python-3-test-failure)
* #23: Replace cgi.parse_qsl w/ six.moves.urllib.parse.parse_qsl (https://bitbucket.org/ianb/paste/pull-request/23/replace-cgiparse_qsl-w)
Fixes issue #8 ("cgi.parse_qsl is pending deprecation") (https://bitbucket.org/ianb/paste/issue/8/cgiparse_qsl-is-pending-deprecation)
* #20: Escape CGI environment variables in HTTP 404 responses (https://bitbucket.org/ianb/paste/pull-request/20/escape-cgi-environment-variables-in-http)
* #6: Add HTTP exception for new code 429 "Too Many Requests" (https://bitbucket.org/ianb/paste/pull-request/6/add-http-exception-for-new-code-429-too)
* #25: replace ``has_key`` method to ``in`` operator #9 (https://bitbucket.org/ianb/paste/pull-request/25/replace-has_key-method-to-in-operator-9)
Fixes #9 ("used methods removed from py3") (https://bitbucket.org/ianb/paste/issue/9/used-methods-removed-from-py3)
* #5: Invalid error message when the socket is already in use (https://bitbucket.org/ianb/paste/issue/5/invalid-error-message-when-the-socket-is)
2.0.1
-----
* Fix setup.py for six dependency: move the six dependency from extras_require
to install_requires.
* Port paste.proxy to Python 3.
* Fix paste.exceptions.serial_number_generator.hash_identifier() on Python 3.
* Fix paste.util.threadedprint.uninstall(). Rename duplicated uninstall()
function to uninstall_stdin() and fix typo in variable name (_oldstin =>
_oldstdin).
* Add README.rst file.
2.0
---
* Experimental Python 3 support.
* paste now requires the six module.
* Drop support of Python 2.5 and older.
* Fixed ``egg:Paste#cgi``
* In ``paste.httpserver``: give a 100 Continue response even when the
server has been configured as an HTTP/1.0 server (clients may send
``Expect: 100-Continue`` before they know the version), and wrap
100 Continue ``environ['wsgi.input']`` files with LimitedLengthFile
just like normal request bodies are wrapped, keeping WSGI
applications from over-reading from the socket.
* Fixed parsing of paths beginning with multiple forward slashes.
* Add tox.ini to run tests with tox on Python 2.6, 2.7 and 3.4.
1.7.5.1
-------
* Fix bug introduced in :mod:`paste.auth.auth_tkt` (with ``url_unquote``)
1.7.5
-----
* Won't install ``tests/`` directory (also caused installation
problems on some Mac systems).
* Fixed problem with gzip middleware and zero-length responses.
* Use ``X-Forwarded-For`` header in :mod:`paste.translogger`
* Fixed problems with mimeparse code
* Fixed some corner cases with CGI scripts
* :mod:`paste.auth.auth_tkt` will URL-quote usernames, avoiding some
errors with usernames with ``!`` in them.
* Improve handling of errors in fetching error pages in
:mod:`paste.errordocument`.
1.7.4
-----
* Fix XSS bug (security issue) with not found handlers for
:class:`paste.urlparser.StaticURLParser` and
:class:`paste.urlmap.URLMap`. If you ask for a path with
``/-->
'''
resources = '''\
'''
def insert_head(body, text):
end_head = re.search(r'', body, re.I)
if end_head:
return body[:end_head.start()] + text + body[end_head.end():]
else:
return text + body
def insert_body(body, text):
end_body = re.search(r'