diff options
| author | Chris McDonough <chrism@plope.com> | 2016-06-01 17:13:27 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2016-06-01 17:13:27 -0400 |
| commit | 3e9a737500e79a6a919ce53db9557c75d874b84c (patch) | |
| tree | ef674c176ab29b9dede8a8fa70c3a18a26edde44 /docs | |
| parent | b5f065906f75efdcc9f80d4f0b8b4092e92b41c0 (diff) | |
| parent | 382f93e2bfec5563587e306fda3fd34759314300 (diff) | |
| download | pyramid-3e9a737500e79a6a919ce53db9557c75d874b84c.tar.gz pyramid-3e9a737500e79a6a919ce53db9557c75d874b84c.tar.bz2 pyramid-3e9a737500e79a6a919ce53db9557c75d874b84c.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
Diffstat (limited to 'docs')
50 files changed, 675 insertions, 407 deletions
diff --git a/docs/Makefile b/docs/Makefile index 546deb30a..411ff35df 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -12,16 +12,20 @@ PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -.PHONY: help clean html web pickle htmlhelp latex changes linkcheck +.PHONY: help clean html text web pickle htmlhelp latex latexpdf changes linkcheck epub doctest help: @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " pickle to make pickle files (usable by e.g. sphinx-web)" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview over all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" + @echo " html to make standalone HTML files" + @echo " text to make text files" + @echo " pickle to make pickle files (usable by e.g. sphinx-web)" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " changes to make an overview over all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " epub to make an epub" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* @@ -90,3 +94,7 @@ epub: @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/api/config.rst b/docs/api/config.rst index e083dbc68..ab3ff0fe1 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -35,6 +35,7 @@ .. automethod:: set_authentication_policy .. automethod:: set_authorization_policy + .. automethod:: set_default_csrf_options .. automethod:: set_default_permission .. automethod:: add_permission @@ -65,6 +66,7 @@ .. automethod:: add_traverser .. automethod:: add_tween .. automethod:: add_route_predicate + .. automethod:: add_subscriber_predicate .. automethod:: add_view_predicate .. automethod:: add_view_deriver .. automethod:: set_request_factory diff --git a/docs/api/index.rst b/docs/api/index.rst index cb38aa0b2..4b912e2bd 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -1,4 +1,4 @@ -.. _html_api_documentation: +.. _api_documentation: API Documentation ================= diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst index 272820a91..521d65d2b 100644 --- a/docs/api/interfaces.rst +++ b/docs/api/interfaces.rst @@ -59,6 +59,9 @@ Other Interfaces .. autointerface:: IRenderer :members: + .. autointerface:: IRequestFactory + :members: + .. autointerface:: IResponseFactory :members: diff --git a/docs/authorintro.rst b/docs/authorintro.rst index ebc6bcff8..6e96fad9a 100644 --- a/docs/authorintro.rst +++ b/docs/authorintro.rst @@ -54,7 +54,14 @@ technologies. Book Content ============ -This book is divided into three major parts: +This book is divided into four major parts: + +:ref:`tutorials` + + Each tutorial builds a sample application or implements a set of + concepts with a sample; it then describes the application or + concepts in terms of the sample. You should read the tutorials if + you want a guided tour of :app:`Pyramid`. :ref:`narrative_documentation` @@ -66,19 +73,16 @@ This book is divided into three major parts: out-of-order, or when you need only a reminder about a particular topic while you're developing an application. -:ref:`tutorials` - - Each tutorial builds a sample application or implements a set of - concepts with a sample; it then describes the application or - concepts in terms of the sample. You should read the tutorials if - you want a guided tour of :app:`Pyramid`. - :ref:`api_documentation` Comprehensive reference material for every public API exposed by :app:`Pyramid`. The API documentation is organized alphabetically by module name. +:ref:`pscripts_documentation` + + ``p*`` scripts included with :app:`Pyramid`. + .. index:: single: repoze.zope2 single: Zope 3 diff --git a/docs/conf.py b/docs/conf.py index 786ff3abf..518f7e784 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -138,6 +138,7 @@ if book: # 'whatsnew-1.4': 'index', # 'whatsnew-1.5': 'index', # 'whatsnew-1.6': 'index', +# 'whatsnew-1.7': 'index', # 'tutorials/gae/index': 'index', # 'api/chameleon_text': 'api', # 'api/chameleon_zpt': 'api', diff --git a/docs/conventions.rst b/docs/conventions.rst index 4469d0c73..43853882c 100644 --- a/docs/conventions.rst +++ b/docs/conventions.rst @@ -35,7 +35,7 @@ References to glossary terms are presented using the following style: URLs are presented using the following style: - `Pylons <http://pylonsproject.org>`_ + `Pylons <http://www.pylonsproject.org>`_ References to sections and chapters are presented using the following style: @@ -55,7 +55,7 @@ character, e.g.: .. code-block:: bash - $ $VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test -q (See :term:`venv` for the meaning of ``$VENV``) @@ -64,7 +64,7 @@ drive letter and/or a directory name, e.g.: .. code-block:: doscon - c:\examples> %VENV%\Scripts\py.test tutorial\tests.py -q + c:\examples> %VENV%\Scripts\py.test -q (See :term:`venv` for the meaning of ``%VENV%``) @@ -73,7 +73,7 @@ example block commands are prefixed only with a ``>`` character, e.g.: .. code-block:: doscon - > %VENV%\Scripts\py.test tutorial\tests.py -q + > %VENV%\Scripts\py.test -q When a command that should be typed on one line is too long to fit on a page, the backslash ``\`` is used to indicate that the following printed line should diff --git a/docs/copyright.rst b/docs/copyright.rst index 3beaee7f7..30ae40603 100644 --- a/docs/copyright.rst +++ b/docs/copyright.rst @@ -1,7 +1,7 @@ Copyright, Trademarks, and Attributions ======================================= -*The Pyramid Web Framework, Version 1.1* +"The Pyramid Web Framework, Version |version|" by Chris McDonough @@ -63,7 +63,7 @@ Contributors: GitHub. Cover Designer: - Hugues Laflamme of `Kemeneur <http://www.kemeneur.com/>`_. + Hugues Laflamme of Kemeneur. Used with permission: @@ -80,8 +80,8 @@ Print Production ---------------- The print version of this book was produced using the `Sphinx -<http://sphinx.pocoo.org/>`_ documentation generation system and the -`LaTeX <http://www.latex-project.org/>`_ typesetting system. +<http://www.sphinx-doc.org/en/stable/>`_ documentation generation system and +the `LaTeX <http://www.latex-project.org/>`_ typesetting system. Contacting The Publisher ------------------------ @@ -90,7 +90,7 @@ Please send documentation licensing inquiries, translation inquiries, and other business communications to `Agendaless Consulting <mailto:webmaster@agendaless.com>`_. Please send software and other technical queries to the `Pylons-devel mailing list -<http://groups.google.com/group/pylons-devel>`_. +<https://groups.google.com/forum/#!forum/pylons-devel>`_. HTML Version and Source Code ---------------------------- @@ -101,4 +101,3 @@ http://docs.pylonsproject.org/projects/pyramid/en/latest/ The source code for the examples used in this book are available within the :app:`Pyramid` software distribution, always available via https://github.com/Pylons/pyramid - diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 5f3295305..f42582e47 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -131,7 +131,7 @@ obvious. First, what's a "utility"? Well, for the purposes of this discussion, and for the purpose of the code above, it's just not very important. If you really want to know, you can read `this -<http://www.muthukadan.net/docs/zca.html#utility>`_. However, still, readers +<http://muthukadan.net/docs/zca.html#utility>`_. However, still, readers of such code need to understand the concept in order to parse it. This is problem number one. @@ -608,7 +608,7 @@ pyramid/scaffolds/ 133KB -pyramid/ (except for ``pyramd/tests`` and ``pyramid/scaffolds``) +pyramid/ (except for ``pyramid/tests`` and ``pyramid/scaffolds``) 812KB @@ -665,7 +665,7 @@ desktop GUI platforms by using similar terminology, and to provide some frame of reference for how various components in the common web framework might hang together. But in the opinion of the author, "MVC" doesn't match the web very well in general. Quoting from the `Model-View-Controller Wikipedia entry -<http://en.wikipedia.org/wiki/Model–view–controller>`_: +<https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller>`_: Though MVC comes in different flavors, control flow is generally as follows: @@ -847,9 +847,9 @@ Challenge +++++++++ :app:`Pyramid` performs automatic authorization checks only at :term:`view` -execution time. Zope 3 wraps context objects with a `security proxy -<http://wiki.zope.org/zope3/WhatAreSecurityProxies>`_, which causes Zope 3 also -to do security checks during attribute access. I like this, because it means: +execution time. Zope 3 wraps context objects with a security proxy, which +causes Zope 3 also to do security checks during attribute access. I like this, +because it means: #) When I use the security proxy machinery, I can have a view that conditionally displays certain HTML elements (like form fields) or @@ -1006,16 +1006,18 @@ the following: Microframeworks have smaller Hello World programs ------------------------------------------------- -Self-described "microframeworks" exist. `Bottle <http://bottle.paws.de>`_ and -`Flask <http://flask.pocoo.org/>`_ are two that are becoming popular. `Bobo -<http://bobo.digicool.com/>`_ doesn't describe itself as a microframework, but -its intended user base is much the same. Many others exist. We've even (only as -a teaching tool, not as any sort of official project) `created one using -Pyramid <http://static.repoze.org/casts/videotags.html>`_. The videos use BFG, -a precursor to Pyramid, but the resulting code is `available for Pyramid too -<https://github.com/Pylons/groundhog>`_). Microframeworks are small frameworks -with one common feature: each allows its users to create a fully functional -application that lives in a single Python file. +Self-described "microframeworks" exist. `Bottle +<http://bottlepy.org/docs/dev/index.html>`_ and `Flask +<http://flask.pocoo.org/>`_ are two that are becoming popular. `Bobo +<http://bobo.digicool.com/en/latest/>`_ doesn't describe itself as a +microframework, but its intended user base is much the same. Many others exist. +We've even (only as a teaching tool, not as any sort of official project) +`created one using Pyramid <http://static.repoze.org/casts/videotags.html>`_. +The videos use BFG, a precursor to Pyramid, but the resulting code is +`available for Pyramid too <https://github.com/Pylons/groundhog>`_). +Microframeworks are small frameworks with one common feature: each allows its +users to create a fully functional application that lives in a single Python +file. Some developers and microframework authors point out that Pyramid's "hello world" single-file program is longer (by about five lines) than the equivalent @@ -1295,12 +1297,12 @@ Consider the following simple `Groundhog from groundhog import Groundhog app = Groundhog('myapp', 'seekrit') - app.route('/admin') + @app.route('/admin') def admin(): return '<html>admin page</html>' - app.route('/:action') - def action(): + @app.route('/:action') + def do_action(action): if action == 'add': return '<html>add</html>' if action == 'delete': @@ -1320,15 +1322,15 @@ order of the function definitions in the file? from groundhog import Groundhog app = Groundhog('myapp', 'seekrit') - app.route('/:action') - def action(): + @app.route('/:action') + def do_action(action): if action == 'add': return '<html>add</html>' if action == 'delete': return '<html>delete</html>' return app.abort(404) - app.route('/admin') + @app.route('/admin') def admin(): return '<html>admin page</html>' @@ -1430,9 +1432,10 @@ object which *is not logically global*: # this is executed if the request method was GET or the # credentials were invalid -The `Pylons 1.X <http://pylonsproject.org>`_ web framework uses a similar -strategy. It calls these things "Stacked Object Proxies", so, for purposes -of this discussion, I'll do so as well. +The `Pylons 1.X +<http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/>`_ +web framework uses a similar strategy. It calls these things "Stacked Object +Proxies", so, for purposes of this discussion, I'll do so as well. Import statements in Python (``import foo``, ``from bar import baz``) are most frequently performed to obtain a reference to an object defined globally @@ -1650,10 +1653,11 @@ If you can understand this hello world program, you can use Pyramid: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -Pyramid has ~ 700 pages of documentation (printed), covering topics from the -very basic to the most advanced. *Nothing* is left undocumented, quite +Pyramid has over 1200 pages of documentation (printed), covering topics from +the very basic to the most advanced. *Nothing* is left undocumented, quite literally. It also has an *awesome*, very helpful community. Visit the -#pyramid IRC channel on freenode.net (irc://freenode.net#pyramid) and see. +`#pyramid IRC channel on freenode.net +<https://webchat.freenode.net/?channels=pyramid>`_ and see. Hate Zope +++++++++ @@ -1701,5 +1705,6 @@ Other Challenges ---------------- Other challenges are encouraged to be sent to the `Pylons-devel -<http://groups.google.com/group/pylons-devel>`_ maillist. We'll try to address -them by considering a design change, or at very least via exposition here. +<https://groups.google.com/forum/#!forum/pylons-devel>`_ maillist. We'll try +to address them by considering a design change, or at very least via exposition +here. diff --git a/docs/glossary.rst b/docs/glossary.rst index 1d97bffe8..9b41b4359 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -36,7 +36,7 @@ Glossary Repoze "Repoze" is essentially a "brand" of software developed by `Agendaless - Consulting <http://agendaless.com>`_ and a set of contributors. The + Consulting <https://agendaless.com>`_ and a set of contributors. The term has no special intrinsic meaning. The project's `website <http://repoze.org>`_ has more information. The software developed "under the brand" is available in a `Subversion repository @@ -51,7 +51,7 @@ Glossary You can use :term:`distribute` under Python 3 instead. distribute - `Distribute <http://packages.python.org/distribute/>`_ is a fork of + `Distribute <https://pythonhosted.org/distribute/>`_ is a fork of :term:`setuptools` which runs on both Python 2 and Python 3. pkg_resources @@ -321,18 +321,18 @@ Glossary :term:`principal` (or principals) associated with a request. WSGI - `Web Server Gateway Interface <http://www.wsgi.org/>`_. This is a - Python standard for connecting web applications to web servers, - similar to the concept of Java Servlets. :app:`Pyramid` requires - that your application be served as a WSGI application. + `Web Server Gateway Interface <http://wsgi.readthedocs.org/en/latest/>`_. + This is a Python standard for connecting web applications to web servers, + similar to the concept of Java Servlets. :app:`Pyramid` requires that + your application be served as a WSGI application. middleware *Middleware* is a :term:`WSGI` concept. It is a WSGI component that acts both as a server and an application. Interesting uses for middleware exist, such as caching, content-transport - encoding, and other functions. See `WSGI.org <http://www.wsgi.org>`_ - or `PyPI <http://python.org/pypi>`_ to find middleware for your - application. + encoding, and other functions. See `WSGI.org + <http://wsgi.readthedocs.org/en/latest/>`_ or `PyPI + <https://pypi.python.org/pypi>`_ to find middleware for your application. pipeline The :term:`PasteDeploy` term for a single configuration of a WSGI @@ -346,15 +346,15 @@ Glossary `A web framework based on Zope 3 <http://grok.zope.org>`_. Django - `A full-featured Python web framework <http://djangoproject.com>`_. + `A full-featured Python web framework <https://www.djangoproject.com/>`_. Pylons `A lightweight Python web framework <http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/>`_ and a predecessor of Pyramid. ZODB - `Zope Object Database <http://zodb.org>`_, a - persistent Python object store. + `Zope Object Database <http://www.zodb.org/en/latest/>`_, a persistent + Python object store. WebOb `WebOb <http://webob.org>`_ is a WSGI request/response @@ -376,28 +376,27 @@ Glossary the box in ZPT and text flavors. ZPT - The `Zope Page Template <http://wiki.zope.org/ZPT/FrontPage>`_ + The `Zope Page Template <http://docs.zope.org/zope2/zope2book/ZPT.html>`_ templating language. METAL - `Macro Expansion for TAL <http://wiki.zope.org/ZPT/METAL>`_, a - part of :term:`ZPT` which makes it possible to share common look - and feel between templates. + `Macro Expansion for TAL + <http://docs.zope.org/zope2/zope2book/AppendixC.html#metal-overview>`_, a + part of :term:`ZPT` which makes it possible to share common look and feel + between templates. Genshi - An `XML templating language <http://pypi.python.org/pypi/Genshi/>`_ + An `XML templating language <https://pypi.python.org/pypi/Genshi/>`_ by Christopher Lenz. Jinja2 - A `text templating language <http://jinja.pocoo.org/2/>`_ by Armin - Ronacher. + A `text templating language <http://jinja.pocoo.org/>`_ by Armin Ronacher. Routes - A `system by Ben Bangert <http://routes.groovie.org/>`_ which - parses URLs and compares them against a number of user defined - mappings. The URL pattern matching syntax in :app:`Pyramid` is - inspired by the Routes syntax (which was inspired by Ruby On - Rails pattern syntax). + A `system by Ben Bangert <http://routes.readthedocs.org/en/latest/>`_ + which parses URLs and compares them against a number of user defined + mappings. The URL pattern matching syntax in :app:`Pyramid` is inspired by + the Routes syntax (which was inspired by Ruby On Rails pattern syntax). route A single pattern matched by the :term:`url dispatch` subsystem, @@ -416,7 +415,7 @@ Glossary Zope Component Architecture The `Zope Component Architecture - <http://www.muthukadan.net/docs/zca.html>`_ (aka ZCA) is a system + <http://muthukadan.net/docs/zca.html>`_ (aka ZCA) is a system which allows for application pluggability and complex dispatching based on objects which implement an :term:`interface`. :app:`Pyramid` uses the ZCA "under the hood" to perform view @@ -442,7 +441,7 @@ Glossary subpath. See :ref:`star_subpath` for more information. interface - A `Zope interface <http://pypi.python.org/pypi/zope.interface>`_ + A `Zope interface <https://pypi.python.org/pypi/zope.interface>`_ object. In :app:`Pyramid`, an interface may be attached to a :term:`resource` object or a :term:`request` object in order to identify that the object is "of a type". Interfaces are used @@ -488,13 +487,13 @@ Glossary repoze.catalog An indexing and search facility (fielded and full-text) based on - `zope.index <http://pypi.python.org/pypi/zope.index>`_. See `the + `zope.index <https://pypi.python.org/pypi/zope.index>`_. See `the documentation <http://docs.repoze.org/catalog>`_ for more information. repoze.who - `Authentication middleware <http://docs.repoze.org/who>`_ for - :term:`WSGI` applications. It can be used by :app:`Pyramid` to + `Authentication middleware <http://repozewho.readthedocs.org/en/latest/>`_ + for :term:`WSGI` applications. It can be used by :app:`Pyramid` to provide authentication information. repoze.workflow @@ -555,7 +554,7 @@ Glossary serialization format. jQuery - A popular `Javascript library <http://jquery.org>`_. + A popular `Javascript library <https://jquery.org>`_. renderer A serializer which converts non-:term:`Response` return values from a @@ -569,10 +568,10 @@ Glossary :ref:`adding_and_overriding_renderers` for more information. mod_wsgi - `mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an Apache - module developed by Graham Dumpleton. It allows :term:`WSGI` - applications (such as applications developed using - :app:`Pyramid`) to be served using the Apache web server. + `mod_wsgi <https://code.google.com/archive/p/modwsgi>`_ is an Apache + module developed by Graham Dumpleton. It allows :term:`WSGI` applications + (such as applications developed using :app:`Pyramid`) to be served using + the Apache web server. view predicate An argument to a :term:`view configuration` which evaluates to @@ -609,7 +608,7 @@ Glossary .. seealso:: - See also `PEP 318 <http://www.python.org/dev/peps/pep-0318/>`_. + See also `PEP 318 <https://www.python.org/dev/peps/pep-0318/>`_. configuration declaration An individual method call made to a :term:`configuration directive`, @@ -683,7 +682,7 @@ Glossary thread local A thread-local variable is one which is essentially a global variable in terms of how it is accessed and treated, however, each `thread - <http://en.wikipedia.org/wiki/Thread_(computer_science)>`_ used by the + <https://en.wikipedia.org/wiki/Thread_(computer_science)>`_ used by the application may have a different value for this same "global" variable. :app:`Pyramid` uses a small number of thread local variables, as described in :ref:`threadlocals_chapter`. @@ -700,8 +699,8 @@ Glossary :ref:`multidict_narr` and :class:`pyramid.interfaces.IMultiDict`. PyPI - `The Python Package Index <http://pypi.python.org/pypi>`_, a - collection of software available for Python. + `The Python Package Index <https://pypi.python.org/pypi>`_, a collection + of software available for Python. Agendaless Consulting A consulting organization formed by Paul Everitt, Tres Seaver, @@ -709,14 +708,14 @@ Glossary .. seealso:: - See also `Agendaless Consulting <http://agendaless.com>`_. + See also `Agendaless Consulting <https://agendaless.com>`_. Jython A `Python implementation <http://www.jython.org/>`_ written for the Java Virtual Machine. Python - The `programming language <http://python.org>`_ in which + The `programming language <https://www.python.org>`_ in which :app:`Pyramid` is written. CPython @@ -736,7 +735,7 @@ Glossary subsystems used by :app:`Pyramid`. Google App Engine - `Google App Engine <http://code.google.com/appengine/>`_ (aka + `Google App Engine <https://cloud.google.com/appengine/>`_ (aka "GAE") is a Python application hosting service offered by Google. :app:`Pyramid` runs on GAE. @@ -913,7 +912,7 @@ Glossary can be used as global application values. WebTest - `WebTest <http://pythonpaste.org/webtest/>`_ is a package which can help + `WebTest <http://webtest.pythonpaste.org/en/latest/>`_ is a package which can help you write functional tests for your WSGI application. view mapper @@ -936,20 +935,19 @@ Glossary ZCML `Zope Configuration Markup Language - <http://www.muthukadan.net/docs/zca.html#zcml>`_, an XML dialect + <http://muthukadan.net/docs/zca.html#zcml>`_, an XML dialect used by Zope and :term:`pyramid_zcml` for configuration tasks. pyramid_handlers An add-on package which allows :app:`Pyramid` users to create classes that are analogues of Pylons 1 "controllers". See - http://docs.pylonsproject.org/projects/pyramid_handlers/dev/ . + http://docs.pylonsproject.org/projects/pyramid_handlers/en/latest/. pyramid_jinja2 :term:`Jinja2` templating system bindings for Pyramid, documented at - http://docs.pylonsproject.org/projects/pyramid_jinja2/dev/ . This - package also includes a scaffold named - ``pyramid_jinja2_starter``, which creates an application package based - on the Jinja2 templating system. + http://docs.pylonsproject.org/projects/pyramid_jinja2/en/latest/. This + package also includes a scaffold named ``pyramid_jinja2_starter``, which + creates an application package based on the Jinja2 templating system. Akhet `Akhet <http://docs.pylonsproject.org/projects/akhet/en/latest/>`_ is a @@ -965,7 +963,7 @@ Glossary distutils The standard system for packaging and distributing Python packages. See - http://docs.python.org/distutils/index.html for more information. + https://docs.python.org/2/distutils/index.html for more information. :term:`setuptools` is actually an *extension* of the Distutils. exception response @@ -1008,7 +1006,7 @@ Glossary used in production applications, because the logger can be configured to log to a file, to UNIX syslog, to the Windows Event Log, or even to email. See its `documentation - <http://docs.pylonsproject.org/projects/pyramid_exclog/dev/>`_. + <http://docs.pylonsproject.org/projects/pyramid_exclog/en/latest/>`_. console script A script written to the ``bin`` (on UNIX, or ``Scripts`` on Windows) diff --git a/docs/index.rst b/docs/index.rst index aecc26d2e..02c35866a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,7 +5,7 @@ The Pyramid Web Framework ========================= :app:`Pyramid` is a small, fast, down-to-earth Python web framework. It is -developed as part of the `Pylons Project <http://docs.pylonsproject.org/>`_. +developed as part of the `Pylons Project <http://www.pylonsproject.org/>`_. It is licensed under a `BSD-like license <http://repoze.org/license.html>`_. Here is one of the simplest :app:`Pyramid` applications you can make: @@ -18,7 +18,7 @@ After you install :app:`Pyramid` and run this application, when you visit this application works. -.. _html_getting_started: +.. _getting_started: Getting Started =============== @@ -60,9 +60,9 @@ platforms. .. toctree:: :maxdepth: 1 - tutorials/wiki2/index.rst - tutorials/wiki/index.rst - tutorials/modwsgi/index.rst + tutorials/wiki2/index + tutorials/wiki/index + tutorials/modwsgi/index .. _support-and-development: @@ -70,15 +70,18 @@ platforms. Support and Development ======================= -The `Pylons Project web site <http://pylonsproject.org/>`_ is the main online -source of :app:`Pyramid` support and development information. +The `Pyramid website <https://trypyramid.com/resources.html>`_ is the main +entry point to :app:`Pyramid` web framework resources for support and +development information. To report bugs, use the `issue tracker <https://github.com/Pylons/pyramid/issues>`_. If you've got questions that aren't answered by this documentation, contact the -`Pylons-discuss maillist <http://groups.google.com/group/pylons-discuss>`_ or -join the `#pyramid IRC channel <irc://irc.freenode.net/#pyramid>`_. +`Pylons-discuss maillist +<https://groups.google.com/forum/#!forum/pylons-discuss>`_ or join the +`#pyramid IRC channel +<https://webchat.freenode.net/?channels=pyramid>`_. Browse and check out tagged and trunk versions of :app:`Pyramid` via the `Pyramid GitHub repository <https://github.com/Pylons/pyramid/>`_. To check out @@ -165,7 +168,7 @@ Comprehensive reference material for every public API exposed by ``p*`` Scripts Documentation ============================ -``p*`` scripts included with :app:`Pyramid`:. +``p*`` scripts included with :app:`Pyramid`. .. toctree:: :maxdepth: 1 diff --git a/docs/latexindex.rst b/docs/latexindex.rst index c4afff212..05199d313 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -14,12 +14,27 @@ Front Matter .. toctree:: :maxdepth: 1 - copyright.rst - conventions.rst - authorintro.rst + copyright + conventions + authorintro + designdefense .. mainmatter:: +.. _tutorials: + +Tutorials +@@@@@@@@@ + +.. toctree:: + :maxdepth: 1 + + quick_tour + quick_tutorial/index + tutorials/wiki2/index + tutorials/wiki/index + tutorials/modwsgi/index + .. _narrative_documentation: Narrative Documentation @@ -68,31 +83,47 @@ Narrative Documentation narr/threadlocals narr/zca -.. _tutorials: - -Tutorials -@@@@@@@@@ +API Documentation +@@@@@@@@@@@@@@@@@ .. toctree:: :maxdepth: 1 + :glob: - tutorials/wiki2/index.rst - tutorials/wiki/index.rst - tutorials/modwsgi/index.rst + api/index + api/* -.. _api_documentation: -API Documentation -@@@@@@@@@@@@@@@@@ +``p*`` Scripts Documentation +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. toctree:: :maxdepth: 1 :glob: - api/* + pscripts/index + pscripts/* + .. backmatter:: +Change History +@@@@@@@@@@@@@@ + +.. toctree:: + :maxdepth: 1 + + whatsnew-1.7 + whatsnew-1.6 + whatsnew-1.5 + whatsnew-1.4 + whatsnew-1.3 + whatsnew-1.2 + whatsnew-1.1 + whatsnew-1.0 + changes + + Glossary and Index @@@@@@@@@@@@@@@@@@ diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index af7d0a349..babfa0a98 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -261,6 +261,7 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.add_view_predicate` - :meth:`pyramid.config.Configurator.add_view_deriver` - :meth:`pyramid.config.Configurator.set_authorization_policy` +- :meth:`pyramid.config.Configurator.set_default_csrf_options` - :meth:`pyramid.config.Configurator.set_default_permission` - :meth:`pyramid.config.Configurator.set_view_mapper` diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 6a952dec9..a8491eabd 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -197,7 +197,7 @@ method returns a :term:`WSGI` application object that can be used by any WSGI server to present an application to a requestor. :term:`WSGI` is a protocol that allows servers to talk to Python applications. We don't discuss :term:`WSGI` in any depth within this book, but you can learn more about it by -visiting `wsgi.org <http://wsgi.org>`_. +reading its `documentation <http://wsgi.readthedocs.org/en/latest/>`_. The :app:`Pyramid` application object, in particular, is an instance of a class representing a :app:`Pyramid` :term:`router`. It has a reference to the diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b776f99e8..49ef29d3f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -300,13 +300,38 @@ added as a property and its result is cached per-request by setting ``reify=True``. This way, we eliminate the overhead of running the function multiple times. +.. testsetup:: group1 + + from pyramid.config import Configurator + + + def total(request, *args): + return sum(args) + + + def prop(request): + print("getting the property") + return "the property" + + + + config = Configurator() + config.add_request_method(total) + config.add_request_method(prop, reify=True) + config.commit() + + from pyramid.scripting import prepare + request = prepare(registry=config.registry)["request"] + +.. doctest:: group1 + >>> request.total(1, 2, 3) 6 >>> request.prop getting the property - the property + 'the property' >>> request.prop - the property + 'the property' To not cache the result of ``request.prop``, set ``property=True`` instead of ``reify=True``. @@ -338,13 +363,42 @@ Here is an example of passing a class to ``Configurator.add_request_method``: We attach and cache an object named ``extra`` to the ``request`` object. +.. testsetup:: group2 + + from pyramid.config import Configurator + from pyramid.decorator import reify + + class ExtraStuff(object): + + def __init__(self, request): + self.request = request + + def total(self, *args): + return sum(args) + + # use @property if you don't want to cache the result + @reify + def prop(self): + print("getting the property") + return "the property" + + config = Configurator() + config.add_request_method(ExtraStuff, 'extra', reify=True) + config.commit() + + from pyramid.scripting import prepare + request = prepare(registry=config.registry)["request"] + +.. doctest:: group2 + >>> request.extra.total(1, 2, 3) 6 >>> request.extra.prop getting the property - the property + 'the property' >>> request.extra.prop - the property + 'the property' + .. index:: single: response factory @@ -1593,8 +1647,9 @@ the user-defined :term:`view callable`: ``csrf_view`` Used to check the CSRF token provided in the request. This element is a - no-op if both the ``require_csrf`` view option and the - ``pyramid.require_default_csrf`` setting are disabled. + no-op if ``require_csrf`` view option is not ``True``. Note there will + always be a ``require_csrf`` option if a default value was assigned via + :meth:`pyramid.config.Configurator.set_default_csrf_options`. ``owrapped_view`` diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 014f314ad..131832aae 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -343,7 +343,7 @@ This will create a new message catalog ``.po`` file in ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. Once the file is there, it can be worked on by a human translator. One tool -which may help with this is `Poedit <http://www.poedit.net/>`_. +which may help with this is `Poedit <https://poedit.net/>`_. Note that :app:`Pyramid` itself ignores the existence of all ``.po`` files. For a running application to have translations available, a ``.mo`` file must @@ -647,7 +647,7 @@ before being rendered: The features represented by attributes of the ``i18n`` namespace of Chameleon will also consult the :app:`Pyramid` translations. See -http://chameleon.readthedocs.org/en/latest/reference.html#id50. +http://chameleon.readthedocs.org/en/latest/reference.html#translation-i18n. .. note:: diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 3e5523262..7d96f4074 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -90,7 +90,7 @@ If You Don't Yet Have a Python Interpreter (Windows) If your Windows system doesn't have a Python interpreter, you'll need to install it by downloading a Python 3.x-series interpreter executable from -`python.org's download section <http://python.org/download/>`_ (the files +`python.org's download section <https://www.python.org/downloads/>`_ (the files labeled "Windows Installer"). Once you've downloaded it, double click on the executable and accept the defaults during the installation process. You may also need to download and install the Python for Windows extensions. @@ -99,7 +99,7 @@ also need to download and install the Python for Windows extensions. Windows <python:using-on-windows>` for full details. .. seealso:: Download and install the `Python for Windows extensions - <http://sourceforge.net/projects/pywin32/files/pywin32/>`_. Carefully read + <https://sourceforge.net/projects/pywin32/files/pywin32/>`_. Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper 32- or 64-bit build and Python version. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 24c9f6b93..de6ac408b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -221,7 +221,7 @@ send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. Examples: -http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation +https://trypyramid.com/resources-extending-pyramid.html Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -881,7 +881,7 @@ new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -http://groups.google.com/group/pylons-discuss/. +https://groups.google.com/forum/#!forum/pylons-discuss. Documentation ~~~~~~~~~~~~~ @@ -903,7 +903,7 @@ What Is The Pylons Project? :app:`Pyramid` is a member of the collection of software published under the Pylons Project. Pylons software is written by a loose-knit community of -contributors. The `Pylons Project website <http://pylonsproject.org>`_ +contributors. The `Pylons Project website <http://www.pylonsproject.org>`_ includes details about how :app:`Pyramid` relates to the Pylons Project. .. index:: @@ -967,9 +967,9 @@ nor discouraging the decision. Other Python web frameworks advertise themselves as members of a class of web frameworks named `model-view-controller -<http://en.wikipedia.org/wiki/Model–view–controller>`_ frameworks. Insofar as -this term has been claimed to represent a class of web frameworks, -:app:`Pyramid` also generally fits into this class. +<https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller>`_ +frameworks. Insofar as this term has been claimed to represent a class of web +frameworks, :app:`Pyramid` also generally fits into this class. .. sidebar:: You Say :app:`Pyramid` is MVC, but Where's the Controller? diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 98315ac9f..c9fecd4f4 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -337,6 +337,31 @@ introspectables in categories not described here. The permission name passed to ``set_default_permission``. +``default csrf options`` + + There will be one and only one introspectable in the ``default csrf options`` + category. It represents a call to the + :meth:`pyramid.config.Configurator.set_default_csrf_options` method. It + will have the following data. + + ``require_csrf`` + + The default value for ``require_csrf`` if left unspecified on calls to + :meth:`pyramid.config.Configurator.add_view`. + + ``token`` + + The name of the token searched in ``request.POST`` to find a valid CSRF + token. + + ``header`` + + The name of the request header searched to find a valid CSRF token. + + ``safe_methods`` + + The list of HTTP methods considered safe and exempt from CSRF checks. + ``views`` Each introspectable in the ``views`` category represents a call to diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 9c6e8a319..c7b4b9d6f 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -292,7 +292,8 @@ Logging Exceptions To log or email exceptions generated by your :app:`Pyramid` application, use the :term:`pyramid_exclog` package. Details about its configuration are in its -`documentation <http://docs.pylonsproject.org/projects/pyramid_exclog/dev/>`_. +`documentation +<http://docs.pylonsproject.org/projects/pyramid_exclog/en/latest/>`_. .. index:: single: TransLogger diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 3e00a295a..02cd8ee3a 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -8,9 +8,7 @@ Much Ado About Traversal .. note:: - This chapter was adapted, with permission, from a blog post by `Rob Miller - <http://blog.nonsequitarian.org/>`_, originally published at - http://blog.nonsequitarian.org/2010/much-ado-about-traversal/. + This chapter was adapted, with permission, from a blog post by Rob Miller. Traversal is an alternative to :term:`URL dispatch` which allows :app:`Pyramid` applications to map URLs to code. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 81fc9acf4..1ce12a938 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -209,19 +209,19 @@ On UNIX: .. code-block:: bash - $ $VENV/bin/py.test myproject/tests.py -q + $ $VENV/bin/py.test -q On Windows: .. code-block:: doscon - > %VENV%\Scripts\py.test myproject\tests.py -q + > %VENV%\Scripts\py.test -q Here's sample output from a test run on UNIX: .. code-block:: bash - $ $VENV/bin/py.test myproject/tests.py -q + $ $VENV/bin/py.test -q .. 2 passed in 0.47 seconds @@ -235,6 +235,26 @@ only two sample tests exist. to a stream of dots. If you don't pass ``-q``, you'll see verbose test result output (which normally isn't very useful). +Alternatively, if you'd like to see test coverage, pass the ``--cov`` option +to ``py.test``: + +.. code-block:: bash + + $ $VENV/bin/py.test --cov -q + +Scaffolds include configuration defaults for ``py.test`` and test coverage. +These configuration files are ``pytest.ini`` and ``.coveragerc``, located at +the root of your package. Without these defaults, we would need to specify the +path to the module on which we want to run tests and coverage. + +.. code-block:: bash + + $ $VENV/bin/py.test --cov=myproject myproject/tests.py -q + +.. seealso:: See py.test's documentation for :ref:`pytest:usage` or invoke + ``py.test -h`` to see its full set of options. + + .. index:: single: running an application single: pserve @@ -584,7 +604,7 @@ only (``127.0.0.1``). The sections after ``# logging configuration`` represent Python's standard library :mod:`logging` module configuration for your application. These sections are passed to the `logging module's config file configuration engine -<http://docs.python.org/howto/logging.html#configuring-logging>`_ when the +<https://docs.python.org/2/howto/logging.html#configuring-logging>`_ when the ``pserve`` or ``pshell`` commands are executed. The default configuration sends application logging output to the standard error output of your terminal. For more information about logging configuration, see :ref:`logging_chapter`. @@ -628,8 +648,8 @@ setup.py sdist``. Due to the information contained in the default ``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` files, ``.ini`` files, ``.rst`` files, graphics files, and template files, as well as ``.py`` files. See -http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template for -more information about the syntax and usage of ``MANIFEST.in``. +https://docs.python.org/2/distutils/sourcedist.html#the-manifest-in-template +for more information about the syntax and usage of ``MANIFEST.in``. Without the presence of a ``MANIFEST.in`` file or without checking your source code into a version control repository, ``setup.py sdist`` places only *Python @@ -647,8 +667,8 @@ files with extensions other than the files named in the project's ``MANIFEST.in`` and you don't make use of a setuptools-compatible version control system, you'll need to edit the ``MANIFEST.in`` file and include the statements necessary to include your new files. See -http://docs.python.org/distutils/sourcedist.html#principle for more information -about how to do this. +https://docs.python.org/2/distutils/sourcedist.html#principle for more +information about how to do this. You can also delete ``MANIFEST.in`` from your project and rely on a setuptools feature which simply causes all files checked into a version control system to @@ -697,21 +717,21 @@ Your application's name can be any string; it is specified in the ``name`` field. The version number is specified in the ``version`` value. A short description is provided in the ``description`` field. The ``long_description`` is conventionally the content of the ``README`` and ``CHANGES`` files appended -together. The ``classifiers`` field is a list of `Trove -<http://pypi.python.org/pypi?%3Aaction=list_classifiers>`_ classifiers -describing your application. ``author`` and ``author_email`` are text fields -which probably don't need any description. ``url`` is a field that should -point at your application project's URL (if any). ``packages=find_packages()`` -causes all packages within the project to be found when packaging the -application. ``include_package_data`` will include non-Python files when the -application is packaged if those files are checked into version control. -``zip_safe=False`` indicates that this package is not safe to use as a zipped -egg; instead it will always unpack as a directory, which is more convenient. -``install_requires`` indicate that this package depends on the ``pyramid`` -package. ``extras_require`` is a Python dictionary that defines what is -required to be installed for running tests. We examined ``entry_points`` in our -discussion of the ``development.ini`` file; this file defines the ``main`` -entry point that represents our project's application. +together. The ``classifiers`` field is a list of `Trove classifiers +<https://pypi.python.org/pypi?%3Aaction=list_classifiers>`_ describing your +application. ``author`` and ``author_email`` are text fields which probably +don't need any description. ``url`` is a field that should point at your +application project's URL (if any). ``packages=find_packages()`` causes all +packages within the project to be found when packaging the application. +``include_package_data`` will include non-Python files when the application is +packaged if those files are checked into version control. ``zip_safe=False`` +indicates that this package is not safe to use as a zipped egg; instead it will +always unpack as a directory, which is more convenient. ``install_requires`` +indicates that this package depends on the ``pyramid`` package. +``extras_require`` is a Python dictionary that defines what is required to be +installed for running tests. We examined ``entry_points`` in our discussion of +the ``development.ini`` file; this file defines the ``main`` entry point that +represents our project's application. Usually you only need to think about the contents of the ``setup.py`` file when distributing your application to other people, when adding Python package @@ -909,10 +929,10 @@ The ``tests.py`` module includes unit tests for your application. :linenos: This sample ``tests.py`` file has one unit test and one functional test defined -within it. These tests are executed when you run ``py.test myproject/tests.py --q``. You may add more tests here as you build your application. You are not -required to write tests to use :app:`Pyramid`. This file is simply provided for -convenience and example. +within it. These tests are executed when you run ``py.test -q``. You may add +more tests here as you build your application. You are not required to write +tests to use :app:`Pyramid`. This file is simply provided for convenience and +example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 50e85813a..e06c78028 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -317,7 +317,7 @@ JSONP Renderer .. versionadded:: 1.1 :class:`pyramid.renderers.JSONP` is a `JSONP -<http://en.wikipedia.org/wiki/JSONP>`_ renderer factory helper which implements +<https://en.wikipedia.org/wiki/JSONP>`_ renderer factory helper which implements a hybrid JSON/JSONP renderer. JSONP is useful for making cross-domain AJAX requests. diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 7cf96ac7d..a1319e45f 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -260,19 +260,28 @@ added to the flash queue, and empties the queue. .. method:: pop_flash(queue='') ->>> request.session.flash('info message') ->>> request.session.pop_flash() -['info message'] +.. testsetup:: + + from pyramid import testing + request = testing.DummyRequest() + +.. doctest:: + + >>> request.session.flash('info message') + >>> request.session.pop_flash() + ['info message'] Calling ``session.pop_flash()`` again like above without a corresponding call to ``session.flash()`` will return an empty list, because the queue has already been popped. ->>> request.session.flash('info message') ->>> request.session.pop_flash() -['info message'] ->>> request.session.pop_flash() -[] +.. doctest:: + + >>> request.session.flash('info message') + >>> request.session.pop_flash() + ['info message'] + >>> request.session.pop_flash() + [] .. index:: single: session.peek_flash @@ -287,15 +296,17 @@ flash storage. .. method:: peek_flash(queue='') ->>> request.session.flash('info message') ->>> request.session.peek_flash() -['info message'] ->>> request.session.peek_flash() -['info message'] ->>> request.session.pop_flash() -['info message'] ->>> request.session.peek_flash() -[] +.. doctest:: + + >>> request.session.flash('info message') + >>> request.session.peek_flash() + ['info message'] + >>> request.session.peek_flash() + ['info message'] + >>> request.session.pop_flash() + ['info message'] + >>> request.session.peek_flash() + [] .. index:: single: preventing cross-site request forgery attacks @@ -305,7 +316,7 @@ Preventing Cross-Site Request Forgery Attacks --------------------------------------------- `Cross-site request forgery -<http://en.wikipedia.org/wiki/Cross-site_request_forgery>`_ attacks are a +<https://en.wikipedia.org/wiki/Cross-site_request_forgery>`_ attacks are a phenomenon whereby a user who is logged in to your website might inadvertantly load a URL because it is linked from, or embedded in, an attacker's website. If the URL is one that may modify or delete data, the consequences can be dire. @@ -396,13 +407,13 @@ named ``X-CSRF-Token``. .. code-block:: python - from pyramid.session import check_csrf_token + from pyramid.session import check_csrf_token - def myview(request): - # Require CSRF Token - check_csrf_token(request) + def myview(request): + # Require CSRF Token + check_csrf_token(request) - # ... + # ... .. _auto_csrf_checking: @@ -414,41 +425,45 @@ Checking CSRF Tokens Automatically :app:`Pyramid` supports automatically checking CSRF tokens on requests with an unsafe method as defined by RFC2616. Any other request may be checked manually. This feature can be turned on globally for an application using the -``pyramid.require_default_csrf`` setting. - -If the ``pyramid.required_default_csrf`` setting is a :term:`truthy string` or -``True`` then the default CSRF token parameter will be ``csrf_token``. If a -different token is desired, it may be passed as the value. Finally, a -:term:`falsey string` or ``False`` will turn off automatic CSRF checking -globally on every request. - -No matter what, CSRF checking may be explicitly enabled or disabled on a -per-view basis using the ``require_csrf`` view option. This option is of the -same format as the ``pyramid.require_default_csrf`` setting, accepting strings -or boolean values. - -If ``require_csrf`` is ``True`` but does not explicitly define a token to -check, then the token name is pulled from whatever was set in the -``pyramid.require_default_csrf`` setting. Finally, if that setting does not -explicitly define a token, then ``csrf_token`` is the token required. This token -name will be required in ``request.POST`` which is the submitted form body. - -It is always possible to pass the token in the ``X-CSRF-Token`` header as well. -There is currently no way to define an alternate name for this header without -performing CSRF checking manually. - -In addition to token based CSRF checks, the automatic CSRF checking will also -check the referrer of the request to ensure that it matches one of the trusted -origins. By default the only trusted origin is the current host, however -additional origins may be configured by setting +:meth:`pyramid.config.Configurator.set_default_csrf_options` directive. +For example: + +.. code-block:: python + + from pyramid.config import Configurator + + config = Configurator() + config.set_default_csrf_options(require_csrf=True) + +CSRF checking may be explicitly enabled or disabled on a per-view basis using +the ``require_csrf`` view option. A value of ``True`` or ``False`` will +override the default set by ``set_default_csrf_options``. For example: + +.. code-block:: python + + @view_config(route_name='hello', require_csrf=False) + def myview(request): + # ... + +When CSRF checking is active, the token and header used to find the +supplied CSRF token will be ``csrf_token`` and ``X-CSRF-Token``, respectively, +unless otherwise overridden by ``set_default_csrf_options``. The token is +checked against the value in ``request.POST`` which is the submitted form body. +If this value is not present, then the header will be checked. + +In addition to token based CSRF checks, if the request is using HTTPS then the +automatic CSRF checking will also check the referrer of the request to ensure +that it matches one of the trusted origins. By default the only trusted origin +is the current host, however additional origins may be configured by setting ``pyramid.csrf_trusted_origins`` to a list of domain names (and ports if they are non standard). If a host in the list of domains starts with a ``.`` then that will allow all subdomains as well as the domain without the ``.``. -If CSRF checks fail then a :class:`pyramid.exceptions.BadCSRFToken` exception -will be raised. This exception may be caught and handled by an -:term:`exception view` but, by default, will result in a ``400 Bad Request`` -response being sent to the client. +If CSRF checks fail then a :class:`pyramid.exceptions.BadCSRFToken` or +:class:`pyramid.exceptions.BadCSRFOrigin` exception will be raised. This +exception may be caught and handled by an :term:`exception view` but, by +default, will result in a ``400 Bad Request`` response being sent to the +client. Checking CSRF Tokens with a View Predicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 9e3a31845..6b3b5fcce 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -448,7 +448,7 @@ templating languages including the following: .. _pyramid_chameleon: http://docs.pylonsproject.org/projects/pyramid-chameleon/en/latest/ -.. _Jinja2: http://jinja.pocoo.org/docs/ +.. _Jinja2: http://jinja.pocoo.org/docs/dev/ .. _pyramid_jinja2: http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/ diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index fcdce4f8d..21b696775 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -128,7 +128,8 @@ you can see DeprecationWarnings printed to the console when the tests run. The ``-Wd`` argument tells Python to print deprecation warnings to the console. See `the Python -W flag documentation -<http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more information. +<https://docs.python.org/2/using/cmdline.html#cmdoption-W>`_ for more +information. As your tests run, deprecation warnings will be printed to the console explaining the deprecation and providing instructions about how to prevent the @@ -215,9 +216,10 @@ around in your application interactively to try to generate them, and remediate as explained in :ref:`testing_under_new_release`. See `the PYTHONWARNINGS environment variable documentation -<http://docs.python.org/using/cmdline.html#envvar-PYTHONWARNINGS>`_ or `the +<https://docs.python.org/2/using/cmdline.html#envvar-PYTHONWARNINGS>`_ or `the Python -W flag documentation -<http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more information. +<https://docs.python.org/2/using/cmdline.html#cmdoption-W>`_ for more +information. Upgrading to the very latest Pyramid release -------------------------------------------- diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c13558008..2472ace31 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -271,8 +271,9 @@ pattern like this: But this will either cause an error at startup time or it won't match properly. You'll want to use a Unicode value as the pattern instead rather than raw bytestring escapes. You can use a high-order Unicode value as the pattern by -using `Python source file encoding <http://www.python.org/dev/peps/pep-0263/>`_ -plus the "real" character in the Unicode pattern in the source, like so: +using `Python source file encoding +<https://www.python.org/dev/peps/pep-0263/>`_ plus the "real" character in the +Unicode pattern in the source, like so: .. code-block:: text @@ -1194,7 +1195,7 @@ If a predicate is a class, just add ``__text__`` property in a standard manner. __text__ = 'my custom class predicate' If a predicate is a method, you'll need to assign it after method declaration -(see `PEP 232 <http://www.python.org/dev/peps/pep-0232/>`_). +(see `PEP 232 <https://www.python.org/dev/peps/pep-0232/>`_). .. code-block:: python :linenos: diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index cfcf532bc..ce1586834 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -27,8 +27,8 @@ functionality to the standard WebOb request, which is documented in the :ref:`request_module` API documentation. WebOb provides objects for HTTP requests and responses. Specifically it does -this by wrapping the `WSGI <http://wsgi.org>`_ request environment and response -status, header list, and app_iter (body) values. +this by wrapping the `WSGI <http://wsgi.readthedocs.org/en/latest/>`_ request +environment and response status, header list, and app_iter (body) values. WebOb request and response objects provide many conveniences for parsing WSGI requests and forming WSGI responses. WebOb is a nice way to represent "raw" @@ -46,7 +46,7 @@ Request ~~~~~~~ The request object is a wrapper around the `WSGI environ dictionary -<http://www.python.org/dev/peps/pep-0333/#environ-variables>`_. This +<https://www.python.org/dev/peps/pep-0333/#environ-variables>`_. This dictionary contains keys for each header, keys that describe the request (including the path and query string), a file-like object for the request body, and a variety of custom keys. You can always access the environ with diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 78af6fd40..b170e5d98 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -699,7 +699,7 @@ We changed ``setup.py`` which means we need to rerun ``$VENV/bin/pip install -e .. code-block:: bash - $ $VENV/bin/py.test --cov=hello_world --cov-report=term-missing hello_world/tests.py + $ $VENV/bin/py.test --cov --cov-report=term-missing This yields the following output. diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index 6b29833bd..66e77491d 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -1,7 +1,7 @@ .. _qtut_forms: ==================================== -18: Forms and Validation With Deform +18: Forms and Validation with Deform ==================================== Schema-driven, autogenerated forms with validation. @@ -19,9 +19,6 @@ Instead there are a variety of form libraries that are easy to use in Pyramid. Deform for our forms. This also gives us :ref:`Colander <colander:overview>` for schemas and validation. -Deform uses styling from Twitter Bootstrap and advanced widgets from popular -JavaScript projects. - Objectives ========== diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 1f2b4da97..62dd570fc 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -79,15 +79,15 @@ will reside as we proceed through the tutorial: .. code-block:: text - └── ~ - └── projects - └── quick_tutorial - ├── env - └── step_one - ├── intro - │ ├── __init__.py - │ └── app.py - └── setup.py + `── ~ + `── projects + `── quick_tutorial + │── env + `── step_one + │── intro + │ │── __init__.py + │ `── app.py + `── setup.py For Linux, the commands to do so are as follows: diff --git a/docs/quick_tutorial/tutorial_approach.rst b/docs/quick_tutorial/tutorial_approach.rst index 6d534fe13..49a6bfd85 100644 --- a/docs/quick_tutorial/tutorial_approach.rst +++ b/docs/quick_tutorial/tutorial_approach.rst @@ -32,14 +32,14 @@ below: .. code-block:: text quick_tutorial - ├── env - └── request_response - ├── tutorial - │ ├── __init__.py - │ ├── tests.py - │ └── views.py - ├── development.ini - └── setup.py + │── env + `── request_response + `── tutorial + │ │── __init__.py + │ │── tests.py + │ `── views.py + │── development.ini + `── setup.py Each of the first-level directories (e.g., ``request_response``) is a *Python project* (except as noted for the ``hello_world`` step). The ``tutorial`` diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index 3cc182d13..c66786b11 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -18,7 +18,7 @@ specific path information for commands and files. ``mod_wsgi``. If you have experience with :app:`Pyramid` and ``mod_wsgi`` on Windows systems, please help us document this experience by submitting documentation to the `Pylons-devel maillist - <http://groups.google.com/group/pylons-devel>`_. + <https://groups.google.com/forum/#!forum/pylons-devel>`_. #. The tutorial assumes you have Apache already installed on your system. If you do not, install Apache 2.X for your platform in @@ -29,7 +29,7 @@ specific path information for commands and files. #. Once you have Apache installed, install ``mod_wsgi``. Use the (excellent) `installation instructions - <http://code.google.com/p/modwsgi/wiki/InstallationInstructions>`_ + <https://code.google.com/archive/p/modwsgi/wikis/InstallationInstructions.wiki>`_ for your platform into your system's Apache installation. #. Create a :term:`virtual environment` which we'll use to install our @@ -44,11 +44,11 @@ specific path information for commands and files. #. Install :app:`Pyramid` into the newly created virtual environment: - .. code-block:: text + .. parsed-literal:: $ cd ~/modwsgi/env - $ $VENV/bin/pip install pyramid - + $ $VENV/bin/pip install "pyramid==\ |release|\ " + #. Create and install your :app:`Pyramid` application. For the purposes of this tutorial, we'll just be using the ``pyramid_starter`` application as a baseline application. Substitute your existing :app:`Pyramid` @@ -119,9 +119,8 @@ specific path information for commands and files. #. Visit ``http://localhost/myapp`` in a browser. You should see the sample application rendered in your browser. -:term:`mod_wsgi` has many knobs and a great variety of deployment -modes. This is just one representation of how you might use it to -serve up a :app:`Pyramid` application. See the `mod_wsgi -configuration documentation -<http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines>`_ for -more in-depth configuration information. +:term:`mod_wsgi` has many knobs and a great variety of deployment modes. This +is just one representation of how you might use it to serve up a :app:`Pyramid` +application. See the `mod_wsgi configuration documentation +<https://code.google.com/archive/p/modwsgi/wikis/ConfigurationGuidelines.wiki>`_ +for more in-depth configuration information. diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index c3037f396..386b880e6 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -36,6 +36,6 @@ Note that this command creates a tarball in the "dist" subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the ``pip install .`` command directly at it. Or you can upload it to `PyPI -<http://pypi.python.org>`_ and share it with the rest of the world, where it -can be downloaded via ``pip install`` remotely like any other package people +<https://pypi.python.org/pypi>`_ and share it with the rest of the world, where +it can be downloaded via ``pip install`` remotely like any other package people download from PyPI. diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index dbf995595..6172b122b 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -97,16 +97,17 @@ Install Pyramid into the virtual Python environment On UNIX ^^^^^^^ -.. code-block:: bash +.. parsed-literal:: - $ $VENV/bin/pip install pyramid + $ $VENV/bin/pip install "pyramid==\ |release|\ " On Windows ^^^^^^^^^^ -.. code-block:: doscon +.. parsed-literal:: + + c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " - c:\> %VENV%\Scripts\pip install pyramid Change directory to your virtual Python environment --------------------------------------------------- @@ -128,6 +129,7 @@ On Windows c:\> cd pyramidtut + .. _making_a_project: Making a project @@ -208,7 +210,7 @@ packages. Success executing this command will show a line like the following: zc.lockfile-1.1.0 zdaemon-4.1.0 zodbpickle-0.6.0 zodburi-2.0 -.. _install-testing-requirements_zodb: +.. _install-testing-requirements-zodb: Install testing requirements ---------------------------- @@ -251,21 +253,23 @@ Run the tests ------------- After you've installed the project in development mode as well as the testing -requirements, you may run the tests for the project. +requirements, you may run the tests for the project. The following commands +provide options to py.test that specify the module for which its tests shall be +run, and to run py.test in quiet mode. On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test -q On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial\tests.py -q + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q For a successful test run, you should see output that ends like this: @@ -291,15 +295,15 @@ On UNIX .. code-block:: bash - $ $VENV/bin/py.test --cov=tutorial --cov-report=term-missing tutorial/tests.py + $ $VENV/bin/py.test --cov --cov-report=term-missing On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ - --cov-report=term-missing tutorial\tests.py + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \ + --cov-report=term-missing If successful, you will see output something like this: @@ -327,6 +331,40 @@ If successful, you will see output something like this: Our package doesn't quite have 100% test coverage. +.. _test_and_coverage_scaffold_defaults_zodb: + +Test and coverage scaffold defaults +----------------------------------- + +Scaffolds include configuration defaults for ``py.test`` and test coverage. +These configuration files are ``pytest.ini`` and ``.coveragerc``, located at +the root of your package. Without these defaults, we would need to specify the +path to the module on which we want to run tests and coverage. + +On UNIX +^^^^^^^ + +.. code-block:: bash + + $ $VENV/bin/py.test --cov=tutorial tutorial/tests.py -q + +On Windows +^^^^^^^^^^ + +.. code-block:: doscon + + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ + --cov-report=term-missing tutorial\tests.py -q + +py.test follows :ref:`conventions for Python test discovery +<pytest:test discovery>`, and the configuration defaults from the scaffold +tell ``py.test`` where to find the module on which we want to run tests and +coverage. + +.. seealso:: See py.test's documentation for :ref:`pytest:usage` or invoke + ``py.test -h`` to see its full set of options. + + .. _wiki-start-the-application: Start the application @@ -357,9 +395,9 @@ If successful, you will see something like this on your console: .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 95736. - serving on http://127.0.0.1:6543 + Starting subprocess with file monitor + Starting server in PID 82349. + serving on http://127.0.0.1:6543 This means the server is ready to accept requests. @@ -386,9 +424,28 @@ assumptions: - You are willing to use :term:`traversal` to map URLs to code. +- You want to use pyramid_zodbconn_, pyramid_tm_, and the transaction_ packages + to manage connections and transactions with :term:`ZODB`. + +- You want to use pyramid_chameleon_ to render your templates. Different + templating engines can be used, but we had to choose one to make this + tutorial. See :ref:`available_template_system_bindings` for some options. + .. note:: - :app:`Pyramid` supports any persistent storage mechanism (e.g., a SQL - database or filesystem files). It also supports an additional - mechanism to map URLs to code (:term:`URL dispatch`). However, for the - purposes of this tutorial, we'll only be using traversal and ZODB. + :app:`Pyramid` supports any persistent storage mechanism (e.g., an SQL + database or filesystem files). It also supports an additional mechanism to + map URLs to code (:term:`URL dispatch`). However, for the purposes of this + tutorial, we'll only be using :term:`traversal` and :term:`ZODB`. + +.. _pyramid_chameleon: + http://docs.pylonsproject.org/projects/pyramid-chameleon/en/latest/ + +.. _pyramid_tm: + http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/ + +.. _pyramid_zodbconn: + http://docs.pylonsproject.org/projects/pyramid-zodbconn/en/latest/ + +.. _transaction: + http://zodb.readthedocs.org/en/latest/transactions.html diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index 788ec595b..85a023cc9 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -52,20 +52,21 @@ Running the tests ================= We can run these tests by using ``py.test`` similarly to how we did in -:ref:`running_tests`. Our testing dependencies have already been satisfied, -courtesy of the scaffold, so we can jump right to running tests. +:ref:`running_tests`. Courtesy of the scaffold, our testing dependencies have +already been satisfied and ``py.test`` and coverage have already been +configured, so we can jump right to running tests. On UNIX: .. code-block:: text - $ $VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test -q On Windows: .. code-block:: text - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial/tests.py -q + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q The expected result should look like the following: diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 6520613ea..9f7b82d1d 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -191,49 +191,49 @@ Success will look something like this: .. code-block:: bash - 2016-04-09 02:49:51,711 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2016-04-09 02:49:51,711 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-04-09 02:49:51,712 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2016-04-09 02:49:51,712 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-04-09 02:49:51,713 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") - 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users") - 2016-04-09 02:49:51,714 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 02:49:51,715 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users") + 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") + 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:12:09,229 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE TABLE users ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - role TEXT NOT NULL, - password_hash TEXT, - CONSTRAINT pk_users PRIMARY KEY (id), - CONSTRAINT uq_users_name UNIQUE (name) + id INTEGER NOT NULL, + name TEXT NOT NULL, + role TEXT NOT NULL, + password_hash TEXT, + CONSTRAINT pk_users PRIMARY KEY (id), + CONSTRAINT uq_users_name UNIQUE (name) ) - 2016-04-09 02:49:51,715 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + 2016-05-22 04:12:09,229 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE TABLE pages ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - data INTEGER NOT NULL, - creator_id INTEGER NOT NULL, - CONSTRAINT pk_pages PRIMARY KEY (id), - CONSTRAINT uq_pages_name UNIQUE (name), - CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) + id INTEGER NOT NULL, + name TEXT NOT NULL, + data TEXT NOT NULL, + creator_id INTEGER NOT NULL, + CONSTRAINT pk_pages PRIMARY KEY (id), + CONSTRAINT uq_pages_name UNIQUE (name), + CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) ) - 2016-04-09 02:49:51,716 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 02:49:51,717 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-04-09 02:49:52,256 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) - 2016-04-09 02:49:52,257 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2016-04-09 02:49:52,257 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', b'$2b$12$APUPJvI/kKxrbQPyQehkR.ggoOM6fFYCZ07SFCkWGltl1wJsKB98y') - 2016-04-09 02:49:52,258 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2016-04-09 02:49:52,258 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', b'$2b$12$GeFnypuQpZyxZLH.sN0akOrPdZMcQjqVTCim67u6f89lOFH/0ddc6') - 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) - 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1) - 2016-04-09 02:49:52,259 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:12:09,782 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2016-05-22 04:12:09,783 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) + 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', b'$2b$12$K/WLVKRl5fMAb6UM58ueTetXlE3rlc5cRK5zFPimK598scXBR/xWC') + 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) + 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', b'$2b$12$JfwLyCJGv3t.RTSmIrh3B.FKXRT9FevkAqafWdK5oq7Hl4mgAQORe') + 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) + 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1) + 2016-05-22 04:12:09,786 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT View the application in a browser diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index f264448b0..f38a733f4 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -35,6 +35,6 @@ Note that this command creates a tarball in the "dist" subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the ``easy_install`` command directly at it. Or you can upload it to `PyPI -<http://pypi.python.org>`_ and share it with the rest of the world, where it -can be downloaded via ``easy_install`` remotely like any other package people -download from PyPI. +<https://pypi.python.org/pypi>`_ and share it with the rest of the world, where +it can be downloaded via ``easy_install`` remotely like any other package +people download from PyPI. diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index f4676345e..a214b1306 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -97,16 +97,16 @@ Install Pyramid into the virtual Python environment On UNIX ^^^^^^^ -.. code-block:: bash +.. parsed-literal:: - $ $VENV/bin/pip install pyramid + $ $VENV/bin/pip install "pyramid==\ |release|\ " On Windows ^^^^^^^^^^ -.. code-block:: doscon +.. parsed-literal:: - c:\> %VENV%\Scripts\pip install pyramid + c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " Install SQLite3 and its development packages @@ -270,21 +270,23 @@ Run the tests ------------- After you've installed the project in development mode as well as the testing -requirements, you may run the tests for the project. +requirements, you may run the tests for the project. The following commands +provide options to py.test that specify the module for which its tests shall be +run, and to run py.test in quiet mode. On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test -q On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test tutorial\tests.py -q + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q For a successful test run, you should see output that ends like this: @@ -310,15 +312,15 @@ On UNIX .. code-block:: bash - $ $VENV/bin/py.test --cov=tutorial --cov-report=term-missing tutorial/tests.py + $ $VENV/bin/py.test --cov --cov-report=term-missing On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ - --cov-report=term-missing tutorial\tests.py + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \ + --cov-report=term-missing If successful, you will see output something like this: @@ -338,21 +340,53 @@ If successful, you will see output something like this: tutorial/models/__init__.py 22 0 100% tutorial/models/meta.py 5 0 100% tutorial/models/mymodel.py 8 0 100% - tutorial/routes.py 3 3 0% 1-3 + tutorial/routes.py 3 2 33% 2-3 tutorial/scripts/__init__.py 0 0 100% - tutorial/scripts/initializedb.py 26 26 0% 1-45 - tutorial/tests.py 39 0 100% + tutorial/scripts/initializedb.py 26 16 38% 22-25, 29-45 tutorial/views/__init__.py 0 0 100% tutorial/views/default.py 12 0 100% - tutorial/views/notfound.py 4 4 0% 1-7 + tutorial/views/notfound.py 4 2 50% 6-7 ---------------------------------------------------------------- - TOTAL 127 39 69% - + TOTAL 88 26 70% ===================== 2 passed in 0.57 seconds ====================== Our package doesn't quite have 100% test coverage. +.. _test_and_coverage_scaffold_defaults_sql: + +Test and coverage scaffold defaults +----------------------------------- + +Scaffolds include configuration defaults for ``py.test`` and test coverage. +These configuration files are ``pytest.ini`` and ``.coveragerc``, located at +the root of your package. Without these defaults, we would need to specify the +path to the module on which we want to run tests and coverage. + +On UNIX +^^^^^^^ + +.. code-block:: bash + + $ $VENV/bin/py.test --cov=tutorial tutorial/tests.py -q + +On Windows +^^^^^^^^^^ + +.. code-block:: doscon + + c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ + --cov-report=term-missing tutorial\tests.py -q + +py.test follows :ref:`conventions for Python test discovery +<pytest:test discovery>`, and the configuration defaults from the scaffold +tell ``py.test`` where to find the module on which we want to run tests and +coverage. + +.. seealso:: See py.test's documentation for :ref:`pytest:usage` or invoke + ``py.test -h`` to see its full set of options. + + .. _initialize_db_wiki2: Initializing the database @@ -396,30 +430,30 @@ The output to your console should be something like this: .. code-block:: bash - 2016-04-09 00:53:37,801 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2016-04-09 00:53:37,801 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-04-09 00:53:37,802 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") - 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2016-05-22 04:03:28,889 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") + 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE TABLE models ( - id INTEGER NOT NULL, - name TEXT, - value INTEGER, - CONSTRAINT pk_models PRIMARY KEY (id) + id INTEGER NOT NULL, + name TEXT, + value INTEGER, + CONSTRAINT pk_models PRIMARY KEY (id) ) - 2016-04-09 00:53:37,803 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 00:53:37,804 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-04-09 00:53:37,805 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) - 2016-04-09 00:53:37,805 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-04-09 00:53:37,806 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-04-09 00:53:37,807 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) - 2016-04-09 00:53:37,808 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) - 2016-04-09 00:53:37,808 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) - 2016-04-09 00:53:37,809 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) + 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2016-05-22 04:03:28,894 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-05-22 04:03:28,896 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) + 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) + 2016-05-22 04:03:28,898 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT Success! You should now have a ``tutorial.sqlite`` file in your current working directory. This is an SQLite database with a single table defined in it @@ -451,7 +485,9 @@ On Windows Your OS firewall, if any, may pop up a dialog asking for authorization to allow python to accept incoming network connections. -If successful, you will see something like this on your console:: +If successful, you will see something like this on your console: + +.. code-block:: text Starting subprocess with file monitor Starting server in PID 82349. @@ -463,7 +499,7 @@ This means the server is ready to accept requests. Visit the application in a browser ---------------------------------- -In a browser, visit http://localhost:6543/. You will see the generated +In a browser, visit http://localhost:6543/. You will see the generated application's default page. One thing you'll notice is the "debug toolbar" icon on right hand side of the @@ -494,19 +530,7 @@ assumptions: :app:`Pyramid` supports any persistent storage mechanism (e.g., object database or filesystem files). It also supports an additional mechanism to map URLs to code (:term:`traversal`). However, for the purposes of this - tutorial, we'll only be using URL dispatch and SQLAlchemy. - -.. _pyramid_jinja2: - http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/ - -.. _pyramid_tm: - http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/ - -.. _zope.sqlalchemy: - https://pypi.python.org/pypi/zope.sqlalchemy - -.. _transaction: - http://zodb.readthedocs.org/en/latest/transactions.html + tutorial, we'll only be using :term:`URL dispatch` and :term:`SQLAlchemy`. .. _pyramid_jinja2: http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/ diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/page.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/page.py index 4dd5b5721..74ff1faf8 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/page.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/page.py @@ -14,7 +14,7 @@ class Page(Base): __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, nullable=False, unique=True) - data = Column(Integer, nullable=False) + data = Column(Text, nullable=False) creator_id = Column(ForeignKey('users.id'), nullable=False) creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py index 6bd3315d6..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash + expected_hash = self.password_hash.encode('utf8') actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py index 4dd5b5721..74ff1faf8 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py @@ -14,7 +14,7 @@ class Page(Base): __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, nullable=False, unique=True) - data = Column(Integer, nullable=False) + data = Column(Text, nullable=False) creator_id = Column(ForeignKey('users.id'), nullable=False) creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py index 6bd3315d6..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash + expected_hash = self.password_hash.encode('utf8') actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False diff --git a/docs/tutorials/wiki2/src/models/tutorial/models/page.py b/docs/tutorials/wiki2/src/models/tutorial/models/page.py index 4dd5b5721..74ff1faf8 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models/page.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models/page.py @@ -14,7 +14,7 @@ class Page(Base): __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, nullable=False, unique=True) - data = Column(Integer, nullable=False) + data = Column(Text, nullable=False) creator_id = Column(ForeignKey('users.id'), nullable=False) creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/models/tutorial/models/user.py b/docs/tutorials/wiki2/src/models/tutorial/models/user.py index 6bd3315d6..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash + expected_hash = self.password_hash.encode('utf8') actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/page.py b/docs/tutorials/wiki2/src/tests/tutorial/models/page.py index 4dd5b5721..74ff1faf8 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/page.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/page.py @@ -14,7 +14,7 @@ class Page(Base): __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, nullable=False, unique=True) - data = Column(Integer, nullable=False) + data = Column(Text, nullable=False) creator_id = Column(ForeignKey('users.id'), nullable=False) creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/user.py b/docs/tutorials/wiki2/src/tests/tutorial/models/user.py index 6bd3315d6..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash + expected_hash = self.password_hash.encode('utf8') actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/page.py b/docs/tutorials/wiki2/src/views/tutorial/models/page.py index 4dd5b5721..74ff1faf8 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/page.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/page.py @@ -14,7 +14,7 @@ class Page(Base): __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, nullable=False, unique=True) - data = Column(Integer, nullable=False) + data = Column(Text, nullable=False) creator_id = Column(ForeignKey('users.id'), nullable=False) creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/user.py b/docs/tutorials/wiki2/src/views/tutorial/models/user.py index 6bd3315d6..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash + expected_hash = self.password_hash.encode('utf8') actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False diff --git a/docs/whatsnew-1.7.rst b/docs/whatsnew-1.7.rst index fd144a24a..398b12f01 100644 --- a/docs/whatsnew-1.7.rst +++ b/docs/whatsnew-1.7.rst @@ -32,6 +32,11 @@ Backwards Incompatibilities csrf token in the query string of a request. Only headers and request bodies are supported. See https://github.com/Pylons/pyramid/pull/2500 +- A global permission set via + :meth:`pyramid.config.Configurator.set_default_permission` will no longer + affect exception views. A permission must be set explicitly on the view for + it to be enforced. See https://github.com/Pylons/pyramid/pull/2534 + Feature Additions ----------------- @@ -42,14 +47,6 @@ Feature Additions other stages of the pipeline such as the raw response from a view or prior to security checks. See https://github.com/Pylons/pyramid/pull/2021 -- Added a new setting, ``pyramid.require_default_csrf`` which may be used - to turn on CSRF checks globally for every request in the application. - This should be considered a good default for websites built on Pyramid. - It is possible to opt-out of CSRF checks on a per-view basis by setting - ``require_csrf=False`` on those views. - See :ref:`auto_csrf_checking` and - https://github.com/Pylons/pyramid/pull/2413 - - Added a ``require_csrf`` view option which will enforce CSRF checks on requests with an unsafe method as defined by RFC2616. If the CSRF check fails a ``BadCSRFToken`` exception will be raised and may be caught by exception @@ -60,6 +57,17 @@ Feature Additions https://github.com/Pylons/pyramid/pull/2413 and https://github.com/Pylons/pyramid/pull/2500 +- Added a new method, + :meth:`pyramid.config.Configurator.set_csrf_default_options`, + for configuring CSRF checks used by the ``require_csrf=True`` view option. + This method can be used to turn on CSRF checks globally for every view + in the application. This should be considered a good default for websites + built on Pyramid. It is possible to opt-out of CSRF checks on a per-view + basis by setting ``require_csrf=False`` on those views. + See :ref:`auto_csrf_checking` and + https://github.com/Pylons/pyramid/pull/2413 and + https://github.com/Pylons/pyramid/pull/2518 + - Added an additional CSRF validation that checks the origin/referrer of a request and makes sure it matches the current ``request.domain``. This particular check is only active when accessing a site over HTTPS as otherwise @@ -96,6 +104,11 @@ Feature Additions ``EXCVIEW`` tween where you may need more control over the request. See https://github.com/Pylons/pyramid/pull/2393 +- A global permission set via + :meth:`pyramid.config.Configurator.set_default_permission` will no longer + affect exception views. A permission must be set explicitly on the view for + it to be enforced. See https://github.com/Pylons/pyramid/pull/2534 + - Allow a leading ``=`` on the key of the request param predicate. For example, ``'=abc=1'`` is equivalent down to ``request.params['=abc'] == '1'``. @@ -111,6 +124,11 @@ Feature Additions :func:`pyramid.paster.setup_logging`. See https://github.com/Pylons/pyramid/pull/2399 +- The :attr:`pyramid.tweens.EXCVIEW` tween will now re-raise the original + exception if no exception view could be found to handle it. This allows + the exception to be handled upstream by another tween or middelware. + See https://github.com/Pylons/pyramid/pull/2567 + Deprecations ------------ |
