From be901601473bd3ba5826d86fb9912843a3517a07 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Wed, 19 Aug 2015 16:32:16 +0200 Subject: Python 3: App must always return binary type. Fixes tests.test_wsgiwrappers.test_wsgirequest_charset --- docs/DeveloperGuidelines.txt | 110 ++++ docs/StyleGuide.txt | 102 ++++ docs/_static/paste.css | 15 + docs/_templates/layout.html | 29 + docs/community/index.txt | 15 + docs/community/mailing-list.txt | 14 + docs/community/repository.txt | 10 + docs/conf.py | 132 +++++ docs/default.css | 394 +++++++++++++ docs/developer-features.txt | 148 +++++ docs/do-it-yourself-framework.txt | 538 +++++++++++++++++ docs/download/index.txt | 32 ++ docs/future.txt | 108 ++++ docs/include/contact.txt | 5 + docs/include/reference_header.txt | 5 + docs/index.txt | 69 +++ docs/license.txt | 20 + docs/modules/auth.auth_tkt.txt | 14 + docs/modules/auth.basic.txt | 11 + docs/modules/auth.cas.txt | 11 + docs/modules/auth.cookie.txt | 12 + docs/modules/auth.digest.txt | 12 + docs/modules/auth.form.txt | 10 + docs/modules/auth.grantip.txt | 10 + docs/modules/auth.multi.txt | 11 + docs/modules/cascade.txt | 10 + docs/modules/cgiapp.txt | 11 + docs/modules/cgitb_catcher.txt | 10 + docs/modules/debug.debugapp.txt | 13 + docs/modules/debug.fsdiff.txt | 15 + docs/modules/debug.prints.txt | 10 + docs/modules/debug.profile.txt | 13 + docs/modules/debug.watchthreads.txt | 12 + docs/modules/debug.wdg_validate.txt | 11 + docs/modules/errordocument.txt | 12 + docs/modules/evalexception.txt | 9 + docs/modules/exceptions.txt | 48 ++ docs/modules/fileapp.txt | 15 + docs/modules/fixture.txt | 40 ++ docs/modules/gzipper.txt | 10 + docs/modules/httpexceptions.txt | 49 ++ docs/modules/httpheaders.txt | 8 + docs/modules/httpserver.txt | 10 + docs/modules/lint.txt | 10 + docs/modules/pony.txt | 10 + docs/modules/progress.txt | 13 + docs/modules/proxy.txt | 14 + docs/modules/recursive.txt | 10 + docs/modules/registry.txt | 13 + docs/modules/reloader.txt | 14 + docs/modules/request.txt | 19 + docs/modules/response.txt | 15 + docs/modules/session.txt | 11 + docs/modules/transaction.txt | 11 + docs/modules/translogger.txt | 10 + docs/modules/url.txt | 10 + docs/modules/urlmap.txt | 11 + docs/modules/urlparser.txt | 14 + docs/modules/util.import_string.txt | 12 + docs/modules/util.multidict.txt | 11 + docs/modules/wsgilib.txt | 18 + docs/modules/wsgiwrappers.txt | 10 + docs/news.txt | 1047 ++++++++++++++++++++++++++++++++++ docs/paste-httpserver-threadpool.txt | 150 +++++ docs/test_server.ini | 42 ++ docs/testing-applications.txt | 156 +++++ docs/url-parsing-with-wsgi.txt | 304 ++++++++++ docs/web/default-site.css | 382 +++++++++++++ docs/web/site.js | 69 +++ docs/web/style.css | 90 +++ 70 files changed, 4619 insertions(+) create mode 100644 docs/DeveloperGuidelines.txt create mode 100644 docs/StyleGuide.txt create mode 100644 docs/_static/paste.css create mode 100644 docs/_templates/layout.html create mode 100644 docs/community/index.txt create mode 100644 docs/community/mailing-list.txt create mode 100644 docs/community/repository.txt create mode 100644 docs/conf.py create mode 100644 docs/default.css create mode 100644 docs/developer-features.txt create mode 100644 docs/do-it-yourself-framework.txt create mode 100644 docs/download/index.txt create mode 100644 docs/future.txt create mode 100644 docs/include/contact.txt create mode 100644 docs/include/reference_header.txt create mode 100644 docs/index.txt create mode 100644 docs/license.txt create mode 100644 docs/modules/auth.auth_tkt.txt create mode 100644 docs/modules/auth.basic.txt create mode 100644 docs/modules/auth.cas.txt create mode 100644 docs/modules/auth.cookie.txt create mode 100644 docs/modules/auth.digest.txt create mode 100644 docs/modules/auth.form.txt create mode 100644 docs/modules/auth.grantip.txt create mode 100644 docs/modules/auth.multi.txt create mode 100644 docs/modules/cascade.txt create mode 100644 docs/modules/cgiapp.txt create mode 100644 docs/modules/cgitb_catcher.txt create mode 100644 docs/modules/debug.debugapp.txt create mode 100644 docs/modules/debug.fsdiff.txt create mode 100644 docs/modules/debug.prints.txt create mode 100644 docs/modules/debug.profile.txt create mode 100644 docs/modules/debug.watchthreads.txt create mode 100644 docs/modules/debug.wdg_validate.txt create mode 100644 docs/modules/errordocument.txt create mode 100644 docs/modules/evalexception.txt create mode 100644 docs/modules/exceptions.txt create mode 100644 docs/modules/fileapp.txt create mode 100644 docs/modules/fixture.txt create mode 100644 docs/modules/gzipper.txt create mode 100644 docs/modules/httpexceptions.txt create mode 100644 docs/modules/httpheaders.txt create mode 100644 docs/modules/httpserver.txt create mode 100644 docs/modules/lint.txt create mode 100644 docs/modules/pony.txt create mode 100644 docs/modules/progress.txt create mode 100644 docs/modules/proxy.txt create mode 100644 docs/modules/recursive.txt create mode 100644 docs/modules/registry.txt create mode 100644 docs/modules/reloader.txt create mode 100644 docs/modules/request.txt create mode 100644 docs/modules/response.txt create mode 100644 docs/modules/session.txt create mode 100644 docs/modules/transaction.txt create mode 100644 docs/modules/translogger.txt create mode 100644 docs/modules/url.txt create mode 100644 docs/modules/urlmap.txt create mode 100644 docs/modules/urlparser.txt create mode 100644 docs/modules/util.import_string.txt create mode 100644 docs/modules/util.multidict.txt create mode 100644 docs/modules/wsgilib.txt create mode 100644 docs/modules/wsgiwrappers.txt create mode 100644 docs/news.txt create mode 100644 docs/paste-httpserver-threadpool.txt create mode 100644 docs/test_server.ini create mode 100644 docs/testing-applications.txt create mode 100644 docs/url-parsing-with-wsgi.txt create mode 100644 docs/web/default-site.css create mode 100644 docs/web/site.js create mode 100644 docs/web/style.css (limited to 'docs') diff --git a/docs/DeveloperGuidelines.txt b/docs/DeveloperGuidelines.txt new file mode 100644 index 0000000..69f39ee --- /dev/null +++ b/docs/DeveloperGuidelines.txt @@ -0,0 +1,110 @@ +++++++++++++++++++++++++++++ +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/``. diff --git a/docs/StyleGuide.txt b/docs/StyleGuide.txt new file mode 100644 index 0000000..b307282 --- /dev/null +++ b/docs/StyleGuide.txt @@ -0,0 +1,102 @@ ++++++++++++++++++++ +Paste Style Guide ++++++++++++++++++++ + +Generally you should follow the recommendations in `PEP 8`_, the +Python Style Guide. Some things to take particular note of: + +.. _PEP 8: http://www.python.org/peps/pep-0008.html + +* **No tabs**. Not anywhere. Always indent with 4 spaces. + +* I don't stress too much on line length. But try to break lines up + by grouping with parenthesis instead of with backslashes (if you + can). Do asserts like:: + + assert some_condition(a, b), ( + "Some condition failed, %r isn't right!" % a) + +* But if you are having problems with line length, maybe you should + just break the expression up into multiple statements. + +* Blank lines between methods, unless they are very small and closely + bound to each other. + +* Don't use the form ``condition and trueValue or falseValue``. Break + it out and use a variable. + +* I (Ian Bicking) am very picky about whitespace. There's one and + only one right way to do it. Good examples:: + + short = 3 + longerVar = 4 + + if x == 4: + do stuff + + func(arg1='a', arg2='b') + func((a + b)*10) + + **Bad** examples:: + + short =3 + longerVar=4 + + if x==4: do stuff + + func(arg1 = 'a', arg2 = 'b') + func(a,b) + func( a, b ) + [ 1, 2, 3 ] + + If the whitespace isn't right, it'll annoy me and I'll feel a need + to fix it. Really, this whitespace stuff shouldn't be that + controversial should it? Some particular points that I feel + strongly about: + + * No space after a function name (bad: ``func (arg)``). + * No space after or before a parenthesis (bad: ``func( arg )``). + * Always one space after a comma (bad: ``func(a,b)``). + +* Use ``@@`` to mark something that is suboptimal, or where you have a + concern that it's not right. Try to also date it and put your + username there. + +* Docstrings are good. They should look like:: + + class AClass(object): + """ + doc string... + """ + + Don't use single quotes (''') -- they tend to cause problems in + Emacs. Don't bother trying make the string less vertically compact. + +* Comments go right before the thing they are commenting on. + +* Methods never, ever, ever start with capital letters. Generally + only classes are capitalized. But definitely never methods. + +* Use ``cls`` to refer to a class. Use ``meta`` to refer to a + metaclass (which also happens to be a class, but calling a metaclass + ``cls`` will be confusing). + +* Use ``isinstance`` instead of comparing types. E.g.:: + + if isinstance(var, str): ... + # Bad: + if type(var) is StringType: ... + +* Never, ever use two leading underscores. This is annoyingly + private. If name clashes are a concern, use explicit name mangling + instead (e.g., ``_MyThing_blahblah``). This is essentially the same + thing as double-underscore, only it's transparent where double + underscore obscures. + +* Module names should be unique in the package. Subpackages shouldn't + share module names with sibling or parent packages. Sadly this + isn't possible for ``__init__.py``, but it's otherwise easy enough. + +* Module names should be all lower case, and probably have no + underscores (smushedwords). + diff --git a/docs/_static/paste.css b/docs/_static/paste.css new file mode 100644 index 0000000..6705e5d --- /dev/null +++ b/docs/_static/paste.css @@ -0,0 +1,15 @@ +a.invisible-link { + color: #fff; + text-decoration: none; +} + +a.invisible-link:visited { + color: #fff; + text-decoration: none; +} + +a.invisible:link { + color: #fff; + text-decoration: none; +} + diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 0000000..6ae2d42 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,29 @@ +{% extends "!layout.html" %} + +{% block extrahead %} +{{ super() }} + +{% endblock %} + +{% block sidebartoc %} +

Python Paste

+ + + +{{ super() }} +{% endblock %} diff --git a/docs/community/index.txt b/docs/community/index.txt new file mode 100644 index 0000000..5b30110 --- /dev/null +++ b/docs/community/index.txt @@ -0,0 +1,15 @@ +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 +`_. + + + diff --git a/docs/community/mailing-list.txt b/docs/community/mailing-list.txt new file mode 100644 index 0000000..854ec3e --- /dev/null +++ b/docs/community/mailing-list.txt @@ -0,0 +1,14 @@ +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 `__ + diff --git a/docs/community/repository.txt b/docs/community/repository.txt new file mode 100644 index 0000000..b8f3700 --- /dev/null +++ b/docs/community/repository.txt @@ -0,0 +1,10 @@ +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 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..e035d50 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,132 @@ +# -*- 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 diff --git a/docs/default.css b/docs/default.css new file mode 100644 index 0000000..a570fb6 --- /dev/null +++ b/docs/default.css @@ -0,0 +1,394 @@ +/* +: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 +} + diff --git a/docs/developer-features.txt b/docs/developer-features.txt new file mode 100644 index 0000000..503d419 --- /dev/null +++ b/docs/developer-features.txt @@ -0,0 +1,148 @@ +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` + diff --git a/docs/do-it-yourself-framework.txt b/docs/do-it-yourself-framework.txt new file mode 100644 index 0000000..ae77ec0 --- /dev/null +++ b/docs/do-it-yourself-framework.txt @@ -0,0 +1,538 @@ +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 ['
Name:
'] + +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 ''' +
+ Name: + +
+ ''' + + 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). diff --git a/docs/download/index.txt b/docs/download/index.txt new file mode 100644 index 0000000..01f918f --- /dev/null +++ b/docs/download/index.txt @@ -0,0 +1,32 @@ +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. diff --git a/docs/future.txt b/docs/future.txt new file mode 100644 index 0000000..697c750 --- /dev/null +++ b/docs/future.txt @@ -0,0 +1,108 @@ +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. diff --git a/docs/include/contact.txt b/docs/include/contact.txt new file mode 100644 index 0000000..87e0bc1 --- /dev/null +++ b/docs/include/contact.txt @@ -0,0 +1,5 @@ +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 +`_. diff --git a/docs/include/reference_header.txt b/docs/include/reference_header.txt new file mode 100644 index 0000000..9b73f85 --- /dev/null +++ b/docs/include/reference_header.txt @@ -0,0 +1,5 @@ +Paste Reference Document +@@@@@@@@@@@@@@@@@@@@@@@@ + +.. contents:: + diff --git a/docs/index.txt b/docs/index.txt new file mode 100644 index 0000000..546e9fb --- /dev/null +++ b/docs/index.txt @@ -0,0 +1,69 @@ +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 +`_. diff --git a/docs/license.txt b/docs/license.txt new file mode 100644 index 0000000..c810dec --- /dev/null +++ b/docs/license.txt @@ -0,0 +1,20 @@ +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. diff --git a/docs/modules/auth.auth_tkt.txt b/docs/modules/auth.auth_tkt.txt new file mode 100644 index 0000000..8622bcf --- /dev/null +++ b/docs/modules/auth.auth_tkt.txt @@ -0,0 +1,14 @@ +: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 + + diff --git a/docs/modules/auth.basic.txt b/docs/modules/auth.basic.txt new file mode 100644 index 0000000..2f8f21f --- /dev/null +++ b/docs/modules/auth.basic.txt @@ -0,0 +1,11 @@ +:mod:`paste.auth.basic` -- Basic HTTP authentication +==================================================== + +.. automodule:: paste.auth.basic + +Module Contents +--------------- + +.. autoclass:: AuthBasicAuthenticator +.. autoclass:: AuthBasicHandler +.. autofunction:: make_basic diff --git a/docs/modules/auth.cas.txt b/docs/modules/auth.cas.txt new file mode 100644 index 0000000..d32dd7a --- /dev/null +++ b/docs/modules/auth.cas.txt @@ -0,0 +1,11 @@ +:mod:`paste.auth.cas` -- CAS authentication +=========================================== + +.. automodule:: paste.auth.cas + +Module Contents +--------------- + +.. autoclass:: AuthCASHandler + + diff --git a/docs/modules/auth.cookie.txt b/docs/modules/auth.cookie.txt new file mode 100644 index 0000000..000cb52 --- /dev/null +++ b/docs/modules/auth.cookie.txt @@ -0,0 +1,12 @@ +:mod:`paste.auth.cookie` -- Cookie-based authentication +======================================================= + +.. automodule:: paste.auth.cookie + +Module Contents +--------------- + +.. autoclass:: AuthCookieSigner +.. autoclass:: AuthCookieHandler +.. autoclass:: AuthCookieEnviron +.. autofunction:: make_auth_cookie diff --git a/docs/modules/auth.digest.txt b/docs/modules/auth.digest.txt new file mode 100644 index 0000000..d13357e --- /dev/null +++ b/docs/modules/auth.digest.txt @@ -0,0 +1,12 @@ +:mod:`paste.auth.digest` -- HTTP Digest login +============================================= + +.. automodule:: paste.auth.digest + +Module Contents +--------------- + +.. autoclass:: AuthDigestAuthenticator +.. autoclass:: AuthDigestHandler +.. autofunction:: digest_password +.. autofunction:: make_digest diff --git a/docs/modules/auth.form.txt b/docs/modules/auth.form.txt new file mode 100644 index 0000000..c059589 --- /dev/null +++ b/docs/modules/auth.form.txt @@ -0,0 +1,10 @@ +:mod:`paste.auth.form` -- HTML form/cookie authentication +========================================================= + +.. automodule:: paste.auth.form + +Module Contents +--------------- + +.. autoclass:: AuthFormHandler +.. autofunction:: make_form diff --git a/docs/modules/auth.grantip.txt b/docs/modules/auth.grantip.txt new file mode 100644 index 0000000..ead45d7 --- /dev/null +++ b/docs/modules/auth.grantip.txt @@ -0,0 +1,10 @@ +:mod:`paste.auth.grantip` -- Set user and groups based on IP address +==================================================================== + +.. automodule:: paste.auth.grantip + +Module Contents +--------------- + +.. autoclass:: GrantIPMiddleware +.. autofunction:: make_grantip diff --git a/docs/modules/auth.multi.txt b/docs/modules/auth.multi.txt new file mode 100644 index 0000000..5813ee7 --- /dev/null +++ b/docs/modules/auth.multi.txt @@ -0,0 +1,11 @@ +:mod:`paste.auth.multi` -- Authentication via one of multiple methods +===================================================================== + +.. automodule:: paste.auth.multi + +Module Contents +--------------- + +.. autoclass:: MultiHandler + + diff --git a/docs/modules/cascade.txt b/docs/modules/cascade.txt new file mode 100644 index 0000000..b54c735 --- /dev/null +++ b/docs/modules/cascade.txt @@ -0,0 +1,10 @@ +:mod:`paste.cascade` -- send requests to multiple applications until success +============================================================================ + +.. automodule:: paste.cascade + +Module Contents +--------------- + +.. autoclass:: Cascade +.. autofunction:: make_cascade diff --git a/docs/modules/cgiapp.txt b/docs/modules/cgiapp.txt new file mode 100644 index 0000000..039ec6d --- /dev/null +++ b/docs/modules/cgiapp.txt @@ -0,0 +1,11 @@ +:mod:`paste.cgiapp` -- run CGI scripts as WSGI applications +=========================================================== + +.. automodule:: paste.cgiapp + +Module Contents +--------------- + +.. autoclass:: CGIApplication +.. autoexception:: CGIError +.. autofunction:: make_cgi_application diff --git a/docs/modules/cgitb_catcher.txt b/docs/modules/cgitb_catcher.txt new file mode 100644 index 0000000..44f8771 --- /dev/null +++ b/docs/modules/cgitb_catcher.txt @@ -0,0 +1,10 @@ +:mod:`paste.cgitb_catcher` -- catch exceptions using cgitb +========================================================== + +.. automodule:: paste.cgitb_catcher + +Module Contents +--------------- + +.. autoclass:: CgitbMiddleware +.. autofunction:: make_cgitb_middleware diff --git a/docs/modules/debug.debugapp.txt b/docs/modules/debug.debugapp.txt new file mode 100644 index 0000000..1eb0a54 --- /dev/null +++ b/docs/modules/debug.debugapp.txt @@ -0,0 +1,13 @@ +:mod:`paste.debug.debugapp` -- debug app +======================================== + +.. automodule:: paste.debug.debugapp + +Module Contents +--------------- + +.. autoclass:: SimpleApplication +.. autoclass:: SlowConsumer +.. autofunction:: make_test_app +.. autofunction:: make_slow_app + diff --git a/docs/modules/debug.fsdiff.txt b/docs/modules/debug.fsdiff.txt new file mode 100644 index 0000000..0a267e7 --- /dev/null +++ b/docs/modules/debug.fsdiff.txt @@ -0,0 +1,15 @@ +: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 + diff --git a/docs/modules/debug.prints.txt b/docs/modules/debug.prints.txt new file mode 100644 index 0000000..1787e71 --- /dev/null +++ b/docs/modules/debug.prints.txt @@ -0,0 +1,10 @@ +:mod:`paste.debug.prints` -- capture print output +================================================= + +.. automodule:: paste.debug.prints + +Module Contents +--------------- + +.. autoclass:: PrintDebugMiddleware + diff --git a/docs/modules/debug.profile.txt b/docs/modules/debug.profile.txt new file mode 100644 index 0000000..ccc0910 --- /dev/null +++ b/docs/modules/debug.profile.txt @@ -0,0 +1,13 @@ +:mod:`paste.debug.profile` -- profile applications and requests +=============================================================== + +.. automodule:: paste.debug.profile + +Module Contents +--------------- + +.. autoclass:: ProfileMiddleware +.. autofunction:: make_profile_middleware +.. autofunction:: profile_decorator + + diff --git a/docs/modules/debug.watchthreads.txt b/docs/modules/debug.watchthreads.txt new file mode 100644 index 0000000..cd0c915 --- /dev/null +++ b/docs/modules/debug.watchthreads.txt @@ -0,0 +1,12 @@ +: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 + diff --git a/docs/modules/debug.wdg_validate.txt b/docs/modules/debug.wdg_validate.txt new file mode 100644 index 0000000..26f7eff --- /dev/null +++ b/docs/modules/debug.wdg_validate.txt @@ -0,0 +1,11 @@ +:mod:`paste.debug.debugapp` -- debug app +======================================== + +.. automodule:: paste.debug.wdg_validate + +Module Contents +--------------- + +.. autoclass:: WDGValidateMiddleware +.. autofunction:: make_wdg_validate_middleware + diff --git a/docs/modules/errordocument.txt b/docs/modules/errordocument.txt new file mode 100644 index 0000000..111ac18 --- /dev/null +++ b/docs/modules/errordocument.txt @@ -0,0 +1,12 @@ +:mod:`paste.errordocument` -- Do internal redirects for error responses +======================================================================= + +.. automodule:: paste.errordocument + +Module Contents +--------------- + +.. autoclass:: StatusBasedForward +.. autofunction:: make_errordocument + + diff --git a/docs/modules/evalexception.txt b/docs/modules/evalexception.txt new file mode 100644 index 0000000..23587fe --- /dev/null +++ b/docs/modules/evalexception.txt @@ -0,0 +1,9 @@ +:mod:`paste.evalexception` -- Interactive debugging for errors +============================================================== + +.. automodule:: paste.evalexception + +Module Contents +--------------- + +.. autoclass:: EvalException diff --git a/docs/modules/exceptions.txt b/docs/modules/exceptions.txt new file mode 100644 index 0000000..dd1a63f --- /dev/null +++ b/docs/modules/exceptions.txt @@ -0,0 +1,48 @@ +: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 diff --git a/docs/modules/fileapp.txt b/docs/modules/fileapp.txt new file mode 100644 index 0000000..dffefd1 --- /dev/null +++ b/docs/modules/fileapp.txt @@ -0,0 +1,15 @@ +:mod:`paste.fileapp` -- Serve files +=================================== + +.. automodule:: paste.fileapp + +Module Contents +--------------- + +.. autoclass:: FileApp +.. autoclass:: DirectoryApp +.. autofunction:: DataApp +.. autofunction:: ArchiveStore + + + diff --git a/docs/modules/fixture.txt b/docs/modules/fixture.txt new file mode 100644 index 0000000..c519ce2 --- /dev/null +++ b/docs/modules/fixture.txt @@ -0,0 +1,40 @@ +: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 + + diff --git a/docs/modules/gzipper.txt b/docs/modules/gzipper.txt new file mode 100644 index 0000000..1036422 --- /dev/null +++ b/docs/modules/gzipper.txt @@ -0,0 +1,10 @@ +:mod:`paste.gzipper` -- Gzip-compress responses +=============================================== + +.. automodule:: paste.gzipper + +Module Contents +--------------- + +.. autoclass:: middleware +.. autofunction:: make_gzip_middleware diff --git a/docs/modules/httpexceptions.txt b/docs/modules/httpexceptions.txt new file mode 100644 index 0000000..736576b --- /dev/null +++ b/docs/modules/httpexceptions.txt @@ -0,0 +1,49 @@ +: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 diff --git a/docs/modules/httpheaders.txt b/docs/modules/httpheaders.txt new file mode 100644 index 0000000..ef5c74b --- /dev/null +++ b/docs/modules/httpheaders.txt @@ -0,0 +1,8 @@ +:mod:`paste.httpheaders` -- Manipulate HTTP Headers +=================================================== + +.. comment: + I just don't feel like documenting the items... + +.. automodule:: paste.httpheaders + :members: diff --git a/docs/modules/httpserver.txt b/docs/modules/httpserver.txt new file mode 100644 index 0000000..5d260c5 --- /dev/null +++ b/docs/modules/httpserver.txt @@ -0,0 +1,10 @@ +:mod:`paste.httpserver` -- HTTP server +====================================== + +.. automodule:: paste.httpserver + +Module Contents +--------------- + +.. autofunction:: serve +.. autofunction:: server_runner diff --git a/docs/modules/lint.txt b/docs/modules/lint.txt new file mode 100644 index 0000000..7a21caf --- /dev/null +++ b/docs/modules/lint.txt @@ -0,0 +1,10 @@ +:mod:`paste.lint` -- Check for the validity of WSGI requests and responses +========================================================================== + +.. automodule:: paste.lint + +Module Contents +--------------- + +.. autofunction:: middleware +.. autoexception:: WSGIWarning diff --git a/docs/modules/pony.txt b/docs/modules/pony.txt new file mode 100644 index 0000000..b2c281b --- /dev/null +++ b/docs/modules/pony.txt @@ -0,0 +1,10 @@ +:mod:`paste.pony` -- Add pony power to your application +======================================================= + +.. automodule:: paste.pony + +Module Contents +--------------- + +.. autoclass:: PonyMiddleware +.. autofunction:: make_pony diff --git a/docs/modules/progress.txt b/docs/modules/progress.txt new file mode 100644 index 0000000..8b15dc8 --- /dev/null +++ b/docs/modules/progress.txt @@ -0,0 +1,13 @@ +:mod:`paste.progress` -- Track progress of uploads +================================================== + +.. automodule:: paste.progress + +Module Contents +--------------- + +.. autoclass:: UploadProgressMonitor +.. autoclass:: UploadProgressReporter + + + diff --git a/docs/modules/proxy.txt b/docs/modules/proxy.txt new file mode 100644 index 0000000..1e6841d --- /dev/null +++ b/docs/modules/proxy.txt @@ -0,0 +1,14 @@ +: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 + + diff --git a/docs/modules/recursive.txt b/docs/modules/recursive.txt new file mode 100644 index 0000000..a9339de --- /dev/null +++ b/docs/modules/recursive.txt @@ -0,0 +1,10 @@ +:mod:`paste.recursive` -- internal requests +=========================================== + +.. automodule:: paste.recursive + +Module Contents +--------------- + +.. autoclass:: RecursiveMiddleware +.. autofunction:: ForwardRequestException diff --git a/docs/modules/registry.txt b/docs/modules/registry.txt new file mode 100644 index 0000000..aba5bce --- /dev/null +++ b/docs/modules/registry.txt @@ -0,0 +1,13 @@ +: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 diff --git a/docs/modules/reloader.txt b/docs/modules/reloader.txt new file mode 100644 index 0000000..fb27333 --- /dev/null +++ b/docs/modules/reloader.txt @@ -0,0 +1,14 @@ +:mod:`paste.reloader` -- Monitor for file changes to restart the process +======================================================================== + +.. automodule:: paste.reloader + +Module Contents +--------------- + +.. autofunction:: install +.. autoclass:: Monitor +.. autofunction:: watch_file + + + diff --git a/docs/modules/request.txt b/docs/modules/request.txt new file mode 100644 index 0000000..d37b129 --- /dev/null +++ b/docs/modules/request.txt @@ -0,0 +1,19 @@ +: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 + + diff --git a/docs/modules/response.txt b/docs/modules/response.txt new file mode 100644 index 0000000..1b6c129 --- /dev/null +++ b/docs/modules/response.txt @@ -0,0 +1,15 @@ +: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 + + diff --git a/docs/modules/session.txt b/docs/modules/session.txt new file mode 100644 index 0000000..6a11dfd --- /dev/null +++ b/docs/modules/session.txt @@ -0,0 +1,11 @@ +:mod:`paste.session` -- Simple file-based sessions +================================================== + +.. automodule:: paste.session + +Module Contents +--------------- + +.. autoclass:: SessionMiddleware +.. autofunction:: make_session_middleware + diff --git a/docs/modules/transaction.txt b/docs/modules/transaction.txt new file mode 100644 index 0000000..1e23a3e --- /dev/null +++ b/docs/modules/transaction.txt @@ -0,0 +1,11 @@ +:mod:`paste.transaction` -- DB-API transactions +=============================================== + +.. automodule:: paste.transaction + +Module Contents +--------------- + +.. autoclass:: TransactionManagerMiddleware +.. autoclass:: ConnectionFactory +.. autofunction:: BasicTransactionHandler diff --git a/docs/modules/translogger.txt b/docs/modules/translogger.txt new file mode 100644 index 0000000..84a7217 --- /dev/null +++ b/docs/modules/translogger.txt @@ -0,0 +1,10 @@ +:mod:`paste.translogger` -- Log requests +======================================== + +.. automodule:: paste.translogger + +Module Contents +--------------- + +.. autoclass:: TransLogger +.. autofunction:: make_filter diff --git a/docs/modules/url.txt b/docs/modules/url.txt new file mode 100644 index 0000000..6b5e83f --- /dev/null +++ b/docs/modules/url.txt @@ -0,0 +1,10 @@ +:mod:`paste.url` -- URL convenience class +========================================= + +.. automodule:: paste.url + +Module Contents +--------------- + +.. autoclass:: URL +.. autoclass:: Image diff --git a/docs/modules/urlmap.txt b/docs/modules/urlmap.txt new file mode 100644 index 0000000..ae584d9 --- /dev/null +++ b/docs/modules/urlmap.txt @@ -0,0 +1,11 @@ +:mod:`paste.urlmap` -- Map URL paths +==================================== + +.. automodule:: paste.urlmap + +Module Contents +--------------- + +.. autoclass:: URLMap +.. autofunction:: urlmap_factory +.. autoclass:: PathProxyURLMap diff --git a/docs/modules/urlparser.txt b/docs/modules/urlparser.txt new file mode 100644 index 0000000..28752ab --- /dev/null +++ b/docs/modules/urlparser.txt @@ -0,0 +1,14 @@ +: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 diff --git a/docs/modules/util.import_string.txt b/docs/modules/util.import_string.txt new file mode 100644 index 0000000..04586d1 --- /dev/null +++ b/docs/modules/util.import_string.txt @@ -0,0 +1,12 @@ +: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 diff --git a/docs/modules/util.multidict.txt b/docs/modules/util.multidict.txt new file mode 100644 index 0000000..58b094a --- /dev/null +++ b/docs/modules/util.multidict.txt @@ -0,0 +1,11 @@ +:mod:`paste.util.multidict` -- Dictionaries with multiple values +================================================================ + +.. automodule:: paste.util.multidict + +Module Contents +--------------- + +.. autoclass:: MultiDict +.. autoclass:: UnicodeMultiDict + diff --git a/docs/modules/wsgilib.txt b/docs/modules/wsgilib.txt new file mode 100644 index 0000000..e40d426 --- /dev/null +++ b/docs/modules/wsgilib.txt @@ -0,0 +1,18 @@ +: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 diff --git a/docs/modules/wsgiwrappers.txt b/docs/modules/wsgiwrappers.txt new file mode 100644 index 0000000..7774854 --- /dev/null +++ b/docs/modules/wsgiwrappers.txt @@ -0,0 +1,10 @@ +:mod:`paste.wsgiwrappers` -- Wrapper functions for WSGI request and response +============================================================================ + +.. automodule:: paste.wsgiwrappers + +Module Contents +--------------- + +.. autoclass:: WSGIRequest +.. autoclass:: WSGIResponse diff --git a/docs/news.txt b/docs/news.txt new file mode 100644 index 0000000..83ff121 --- /dev/null +++ b/docs/news.txt @@ -0,0 +1,1047 @@ +News +==== + +.. contents:: + +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 + ``/-->