From a26e3298ddd73ad782132f9b1098e02f7ed55c42 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 4 Dec 2015 02:39:39 -0800 Subject: update references to references to python-distribute.org (see #2141 for discussion) --- docs/narr/project.rst | 4 ++-- docs/narr/scaffolding.rst | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 25f3931e9..ec40bc67c 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -680,8 +680,8 @@ testing, packaging, and distributing your application. ``setup.py`` is the de facto standard which Python developers use to distribute their reusable code. You can read more about ``setup.py`` files and their usage in the `Setuptools documentation - `_ and `The Hitchhiker's - Guide to Packaging `_. + `_ and `Python Packaging + User Guide `_. Our generated ``setup.py`` looks like this: diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 8677359de..164ceb3bf 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -22,10 +22,10 @@ found by the ``pcreate`` command. To create a scaffold template, create a Python :term:`distribution` to house the scaffold which includes a ``setup.py`` that relies on the ``setuptools`` -package. See `Creating a Package -`_ for more information about -how to do this. For example, we'll pretend the distribution you create is -named ``CoolExtension``, and it has a package directory within it named +package. See `Packaging and Distributing Projects +`_ for more information +about how to do this. For example, we'll pretend the distribution you create +is named ``CoolExtension``, and it has a package directory within it named ``coolextension``. Once you've created the distribution, put a "scaffolds" directory within your -- cgit v1.2.3 From d4177a51aff1a46d1c2223db6ed7afd99964e8ad Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Dec 2015 01:41:06 -0800 Subject: update narrative docs and literalinclude source files that use the starter scaffold to reflect its current state --- docs/narr/MyProject/development.ini | 6 +- .../MyProject/myproject/templates/mytemplate.pt | 13 +-- docs/narr/MyProject/myproject/tests.py | 1 + docs/narr/MyProject/production.ini | 2 +- docs/narr/MyProject/setup.py | 45 ++++------- docs/narr/project.rst | 94 ++++++++++++---------- 6 files changed, 81 insertions(+), 80 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index a9a26e56b..749e574eb 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -11,7 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = +pyramid.includes = pyramid_debugtoolbar # By default, the toolbar only appears for clients from IP addresses @@ -24,7 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 0.0.0.0 +host = 127.0.0.1 port = 6543 ### @@ -57,4 +57,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index e6b00a145..65d7f0609 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -8,12 +8,12 @@ - Starter Template for The Pyramid Web Framework + Starter Scaffold for The Pyramid Web Framework - + @@ -33,19 +33,20 @@
-

Pyramid starter template

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework.

+

Pyramid Starter scaffold

+

Welcome to ${project}, an application generated by
the Pyramid Web Framework 1.6b2.

diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index 8c60407e5..63d00910c 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -16,6 +16,7 @@ class ViewTests(unittest.TestCase): info = my_view(request) self.assertEqual(info['project'], 'MyProject') + class ViewIntegrationTests(unittest.TestCase): def setUp(self): """ This sets up the application registry with the diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 9eae9e03f..3ccbe6619 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -51,4 +51,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 9f34540a7..8c019af51 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -1,42 +1,30 @@ -"""Setup for the MyProject package. - -""" import os -from setuptools import setup, find_packages - - -HERE = os.path.abspath(os.path.dirname(__file__)) - -with open(os.path.join(HERE, 'README.txt')) as fp: - README = fp.read() - - -with open(os.path.join(HERE, 'CHANGES.txt')) as fp: - CHANGES = fp.read() +from setuptools import setup, find_packages +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() -REQUIRES = [ +requires = [ 'pyramid', 'pyramid_chameleon', 'pyramid_debugtoolbar', 'waitress', ] -TESTS_REQUIRE = [ - 'webtest' - ] - setup(name='MyProject', version='0.0', description='MyProject', long_description=README + '\n\n' + CHANGES, classifiers=[ - 'Programming Language :: Python', - 'Framework :: Pyramid', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', - ], + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], author='', author_email='', url='', @@ -44,10 +32,11 @@ setup(name='MyProject', packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=REQUIRES, - tests_require=TESTS_REQUIRE, - test_suite='myproject', + install_requires=requires, + tests_require=requires, + test_suite="myproject", entry_points="""\ [paste.app_factory] main = myproject:main - """) + """, + ) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ec40bc67c..4785b60c4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -77,7 +77,7 @@ The below example uses the ``pcreate`` command to create a project with the On UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/pcreate -s starter MyProject @@ -90,7 +90,7 @@ Or on Windows: Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/pcreate -s starter MyProject Creating template pyramid @@ -158,7 +158,7 @@ created project directory. On UNIX: -.. code-block:: text +.. code-block:: bash $ cd MyProject $ $VENV/bin/python setup.py develop @@ -172,7 +172,7 @@ Or on Windows: Elided output from a run of this command on UNIX is shown below: -.. code-block:: text +.. code-block:: bash $ cd MyProject $ $VENV/bin/python setup.py develop @@ -198,7 +198,7 @@ directory of your virtualenv). On UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/python setup.py test -q @@ -210,7 +210,7 @@ Or on Windows: Here's sample output from a test run on UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/python setup.py test -q running test @@ -221,11 +221,23 @@ Here's sample output from a test run on UNIX: writing dependency_links to MyProject.egg-info/dependency_links.txt writing entry points to MyProject.egg-info/entry_points.txt reading manifest file 'MyProject.egg-info/SOURCES.txt' + reading manifest template 'MANIFEST.in' + warning: no files found matching '*.cfg' + warning: no files found matching '*.rst' + warning: no files found matching '*.ico' under directory 'myproject' + warning: no files found matching '*.gif' under directory 'myproject' + warning: no files found matching '*.jpg' under directory 'myproject' + warning: no files found matching '*.txt' under directory 'myproject' + warning: no files found matching '*.mak' under directory 'myproject' + warning: no files found matching '*.mako' under directory 'myproject' + warning: no files found matching '*.js' under directory 'myproject' + warning: no files found matching '*.html' under directory 'myproject' + warning: no files found matching '*.xml' under directory 'myproject' writing manifest file 'MyProject.egg-info/SOURCES.txt' running build_ext - .. + . ---------------------------------------------------------------------- - Ran 1 test in 0.108s + Ran 1 test in 0.008s OK @@ -256,7 +268,7 @@ file. In our case, this file is named ``development.ini``. On UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/pserve development.ini @@ -268,38 +280,38 @@ On Windows: Here's sample output from a run of ``pserve`` on UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/pserve development.ini - Starting server in PID 16601. - serving on http://0.0.0.0:6543 - -When you use ``pserve`` to start the application implied by the default -rendering of a scaffold, it will respond to requests on *all* IP addresses -possessed by your system, not just requests to ``localhost``. This is what the -``0.0.0.0`` in ``serving on http://0.0.0.0:6543`` means. The server will -respond to requests made to ``127.0.0.1`` and on any external IP address. For -example, your system might be configured to have an external IP address -``192.168.1.50``. If that's the case, if you use a browser running on the same -system as Pyramid, it will be able to access the application via -``http://127.0.0.1:6543/`` as well as via ``http://192.168.1.50:6543/``. -However, *other people* on other computers on the same network will also be -able to visit your Pyramid application in their browser by visiting -``http://192.168.1.50:6543/``. - -If you want to restrict access such that only a browser running on the same -machine as Pyramid will be able to access your Pyramid application, edit the + Starting server in PID 16208. + serving on http://127.0.0.1:6543 + +Access is restricted such that only a browser running on the same machine as +Pyramid will be able to access your Pyramid application. However, if you want +to open access to other machines on the same network, then edit the ``development.ini`` file, and replace the ``host`` value in the -``[server:main]`` section. Change it from ``0.0.0.0`` to ``127.0.0.1``. For +``[server:main]`` section, changing it from ``127.0.0.1`` to ``0.0.0.0``. For example: .. code-block:: ini [server:main] use = egg:waitress#main - host = 127.0.0.1 + host = 0.0.0.0 port = 6543 +Now when you use ``pserve`` to start the application, it will respond to +requests on *all* IP addresses possessed by your system, not just requests to +``localhost``. This is what the ``0.0.0.0`` in +``serving on http://0.0.0.0:6543`` means. The server will respond to requests +made to ``127.0.0.1`` and on any external IP address. For example, your system +might be configured to have an external IP address ``192.168.1.50``. If that's +the case, if you use a browser running on the same system as Pyramid, it will +be able to access the application via ``http://127.0.0.1:6543/`` as well as via +``http://192.168.1.50:6543/``. However, *other people* on other computers on +the same network will also be able to visit your Pyramid application in their +browser by visiting ``http://192.168.1.50:6543/``. + You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the ``port = 6543`` line in the ``development.ini`` file's ``[server:main]`` @@ -347,7 +359,7 @@ For example, on UNIX: $ $VENV/bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. - serving on http://0.0.0.0:6543 + serving on http://127.0.0.1:6543 Now if you make a change to any of your project's ``.py`` files or ``.ini`` files, you'll see the server restart automatically: @@ -357,7 +369,7 @@ files, you'll see the server restart automatically: development.ini changed; reloading... -------------------- Restarting -------------------- Starting server in PID 16602. - serving on http://0.0.0.0:6543 + serving on http://127.0.0.1:6543 Changes to template files (such as ``.pt`` or ``.mak`` files) won't cause the server to restart. Changes to template files don't require a server restart as @@ -579,18 +591,16 @@ file. The name ``main`` is a convention used by PasteDeploy signifying that it is the default application. The ``[server:main]`` section of the configuration file configures a WSGI -server which listens on TCP port 6543. It is configured to listen on all -interfaces (``0.0.0.0``). This means that any remote system which has TCP -access to your system can see your Pyramid application. +server which listens on TCP port 6543. It is configured to listen on localhost +only (``127.0.0.1``). .. _MyProject_ini_logging: -The sections that live between the markers ``# Begin logging configuration`` -and ``# End logging configuration`` represent Python's standard library -:mod:`logging` module configuration for your application. The sections between -these two markers are passed to the `logging module's config file configuration -engine `_ when -the ``pserve`` or ``pshell`` commands are executed. The default configuration +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 +`_ 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`. @@ -912,7 +922,7 @@ The ``tests.py`` module includes unit tests for your application. .. literalinclude:: MyProject/myproject/tests.py :language: python - :lines: 1-18 + :lines: 1-17 :linenos: This sample ``tests.py`` file has a single unit test defined within it. This -- cgit v1.2.3 From bf8014ec3458b46c427706988a8ca26380707cd7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Dec 2015 02:43:14 -0800 Subject: update narrative docs and literalinclude source files that use the starter scaffold to reflect its current state --- docs/narr/startup.rst | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 485f6b181..3e168eaea 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -6,15 +6,15 @@ Startup When you cause a :app:`Pyramid` application to start up in a console window, you'll see something much like this show up on the console: -.. code-block:: text +.. code-block:: bash - $ pserve development.ini - Starting server in PID 16601. - serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 + $ $VENV/bin/pserve development.ini + Starting server in PID 16305. + serving on http://127.0.0.1:6543 This chapter explains what happens between the time you press the "Return" key on your keyboard after typing ``pserve development.ini`` and the time the line -``serving on 0.0.0.0:6543 ...`` is output to your console. +``serving on http://127.0.0.1:6543`` is output to your console. .. index:: single: startup process @@ -92,11 +92,11 @@ Here's a high-level time-ordered overview of what happens when you press In this case, the ``myproject.__init__:main`` function referred to by the entry point URI ``egg:MyProject`` (see :ref:`MyProject_ini` for more information about entry point URIs, and how they relate to callables) will - receive the key/value pairs ``{'pyramid.reload_templates':'true', - 'pyramid.debug_authorization':'false', 'pyramid.debug_notfound':'false', - 'pyramid.debug_routematch':'false', 'pyramid.debug_templates':'true', - 'pyramid.default_locale_name':'en'}``. See :ref:`environment_chapter` for - the meanings of these keys. + receive the key/value pairs ``{pyramid.reload_templates = true, + pyramid.debug_authorization = false, pyramid.debug_notfound = false, + pyramid.debug_routematch = false, pyramid.default_locale_name = en, and + pyramid.includes = pyramid_debugtoolbar}``. See :ref:`environment_chapter` + for the meanings of these keys. #. The ``main`` function first constructs a :class:`~pyramid.config.Configurator` instance, passing the ``settings`` @@ -131,10 +131,9 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = egg:waitress#main``), and it will listen on all interfaces (``host = - 0.0.0.0``), on port number 6543 (``port = 6543``). The server code itself - is what prints ``serving on 0.0.0.0:6543 view at http://127.0.0.1:6543``. - The server serves the application, and the application is running, waiting - to receive requests. + 127.0.0.1``), on port number 6543 (``port = 6543``). The server code itself + is what prints ``serving on http://127.0.0.1:6543``. The server serves the + application, and the application is running, waiting to receive requests. .. seealso:: Logging configuration is described in the :ref:`logging_chapter` chapter. -- cgit v1.2.3 From eedef93f0c4c52ea11320bcd49386262fa7293a1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 8 Dec 2015 11:12:38 -0600 Subject: update the cache busting narrative to use add_cache_buster --- docs/narr/assets.rst | 103 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 31 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 0f819570c..8b41f9b8a 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -366,8 +366,7 @@ resource and requests the asset, regardless of any caching policy set for the resource's old URL. :app:`Pyramid` can be configured to produce cache busting URLs for static -assets by passing the optional argument, ``cachebust`` to -:meth:`~pyramid.config.Configurator.add_static_view`: +assets using :meth:`~pyramid.config.Configurator.add_cache_buster`: .. code-block:: python :linenos: @@ -376,14 +375,18 @@ assets by passing the optional argument, ``cachebust`` to from pyramid.static import QueryStringConstantCacheBuster # config is an instance of pyramid.config.Configurator - config.add_static_view( - name='static', path='mypackage:folder/static', - cachebust=QueryStringConstantCacheBuster(str(int(time.time()))), - ) + config.add_static_view(name='static', path='mypackage:folder/static/') + config.add_cache_buster( + 'mypackage:folder/static/', + QueryStringConstantCacheBuster(str(int(time.time())))) + +.. note:: + The trailing slash on the ``add_cache_buster`` call is important to + indicate that it is overriding every asset in the folder and not just a + file named ``static``. -Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache -busting scheme which adds the curent time for a static asset to the query -string in the asset's URL: +Adding the cachebuster instructs :app:`Pyramid` to add the current time for +a static asset to the query string in the asset's URL: .. code-block:: python :linenos: @@ -392,10 +395,7 @@ string in the asset's URL: # Returns: 'http://www.example.com/static/js/myapp.js?x=1445318121' When the web server restarts, the time constant will change and therefore so -will its URL. Supplying the ``cachebust`` argument also causes the static -view to set headers instructing clients to cache the asset for ten years, -unless the ``cache_max_age`` argument is also passed, in which case that -value is used. +will its URL. .. note:: @@ -410,7 +410,7 @@ Disabling the Cache Buster It can be useful in some situations (e.g., development) to globally disable all configured cache busters without changing calls to -:meth:`~pyramid.config.Configurator.add_static_view`. To do this set the +:meth:`~pyramid.config.Configurator.add_cache_buster`. To do this set the ``PYRAMID_PREVENT_CACHEBUST`` environment variable or the ``pyramid.prevent_cachebust`` configuration value to a true value. @@ -419,9 +419,9 @@ configured cache busters without changing calls to Customizing the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``cachebust`` option to -:meth:`~pyramid.config.Configurator.add_static_view` may be set to any object -that implements the interface :class:`~pyramid.interfaces.ICacheBuster`. +Calls to :meth:`~pyramid.config.Configurator.add_cache_buster` may use +any object that implements the interface +:class:`~pyramid.interfaces.ICacheBuster`. :app:`Pyramid` ships with a very simplistic :class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an @@ -461,8 +461,30 @@ the hash of the current commit: def tokenize(self, pathspec): return self.sha1 -Choosing a Cache Buster -~~~~~~~~~~~~~~~~~~~~~~~ +A simple cache buster that modifies the path segment can be constructed as +well: + +.. code-block:: python + :linenos: + + import posixpath + + def cache_buster(spec, subpath, kw): + base_subpath, ext = posixpath.splitext(subpath) + new_subpath = base_subpath + '-asdf' + ext + return new_subpath, kw + +The caveat with this approach is that modifying the path segment +changes the file name, and thus must match what is actually on the +filesystem in order for :meth:`~pyramid.config.Configurator.add_static_view` +to find the file. It's better to use the +:class:`~pyramid.static.ManifestCacheBuster` for these situations, as +described in the next section. + +.. _path_segment_cache_busters: + +Path Segments and Choosing a Cache Buster +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Many caching HTTP proxies will fail to cache a resource if the URL contains a query string. Therefore, in general, you should prefer a cache busting @@ -504,8 +526,11 @@ The following code would set up a cachebuster: config.add_static_view( name='http://mycdn.example.com/', - path='mypackage:static', - cachebust=ManifestCacheBuster('myapp:static/manifest.json')) + path='mypackage:static') + + config.add_cache_buster( + 'mypackage:static/', + ManifestCacheBuster('myapp:static/manifest.json')) A simpler approach is to use the :class:`~pyramid.static.QueryStringConstantCacheBuster` to generate a global @@ -524,8 +549,11 @@ start up as a cachebust token: config.add_static_view( name='http://mycdn.example.com/', - path='mypackage:static', - cachebust=QueryStringConstantCacheBuster(str(int(time.time())))) + path='mypackage:static') + + config.add_cache_buster( + 'mypackage:static/', + QueryStringConstantCacheBuster(str(int(time.time())))) .. index:: single: static assets view @@ -536,25 +564,38 @@ CSS and JavaScript source and cache busting Often one needs to refer to images and other static assets inside CSS and JavaScript files. If cache busting is active, the final static asset URL is not available until the static assets have been assembled. These URLs cannot be -handwritten. Thus, when having static asset references in CSS and JavaScript, -one needs to perform one of the following tasks: +handwritten. Below is an example of how to integrate the cache buster into +the entire stack. Remember, it is just an example and should be modified to +fit your specific tools. -* Process the files by using a precompiler which rewrites URLs to their final - cache busted form. Then, you can use the +* First, process the files by using a precompiler which rewrites URLs to their + final cache-busted form. Then, you can use the :class:`~pyramid.static.ManifestCacheBuster` to synchronize your asset pipeline with :app:`Pyramid`, allowing the pipeline to have full control over the final URLs of your assets. -* Templatize JS and CSS, and call ``request.static_url()`` inside their - template code. +Now that you are able to generate static URLs within :app:`Pyramid`, +you'll need to handle URLs that are out of our control. To do this you may +use some of the following options to get started: -* Pass static URL references to CSS and JavaScript via other means. +* Configure your asset pipeline to rewrite URL references inline in + CSS and JavaScript. This is the best approach because then the files + may be hosted by :app:`Pyramid` or an external CDN without haven't to + change anything. They really are static. + +* Templatize JS and CSS, and call ``request.static_url()`` inside their + template code. While this approach may work in certain scenarios, it is not + recommended because your static assets will not really be static and are now + dependent on :app:`Pyramid` to be served correctly. See + :ref:`advanced static` for more information on this approach. If your CSS and JavaScript assets use URLs to reference other assets it is recommended that you implement an external asset pipeline that can rewrite the generated static files with new URLs containing cache busting tokens. The machinery inside :app:`Pyramid` will not help with this step as it has very -little knowledge of the asset types your application may use. +little knowledge of the asset types your application may use. The integration +into :app:`Pyramid` is simply for linking those assets into your HTML and +other dynamic content. .. _advanced_static: -- cgit v1.2.3 From 3175c990bc02805b729594996f6360b81f5f0ebc Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 9 Dec 2015 23:01:35 -0600 Subject: fix broken ref in docs --- docs/narr/assets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 8b41f9b8a..0e3f6af11 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -587,7 +587,7 @@ use some of the following options to get started: template code. While this approach may work in certain scenarios, it is not recommended because your static assets will not really be static and are now dependent on :app:`Pyramid` to be served correctly. See - :ref:`advanced static` for more information on this approach. + :ref:`advanced_static` for more information on this approach. If your CSS and JavaScript assets use URLs to reference other assets it is recommended that you implement an external asset pipeline that can rewrite the -- cgit v1.2.3 From 312aa1b996f786dc18d8189a7a6d9813ad609645 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 14 Dec 2015 02:26:32 -0800 Subject: - Remove broken integration test example from testing and source file, per #2172 - Update functional test with explicit instructions and to sync with actual starter scaffold --- docs/narr/MyProject/myproject/tests.py | 26 ------------ docs/narr/testing.rst | 73 +++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 57 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index 63d00910c..37df08a2a 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -17,32 +17,6 @@ class ViewTests(unittest.TestCase): self.assertEqual(info['project'], 'MyProject') -class ViewIntegrationTests(unittest.TestCase): - def setUp(self): - """ This sets up the application registry with the - registrations your application declares in its ``includeme`` - function. - """ - self.config = testing.setUp() - self.config.include('myproject') - - def tearDown(self): - """ Clear out the application registry """ - testing.tearDown() - - def test_my_view(self): - from myproject.views import my_view - request = testing.DummyRequest() - result = my_view(request) - self.assertEqual(result.status, '200 OK') - body = result.app_iter[0] - self.assertTrue('Welcome to' in body) - self.assertEqual(len(result.headerlist), 2) - self.assertEqual(result.headerlist[0], - ('Content-Type', 'text/html; charset=UTF-8')) - self.assertEqual(result.headerlist[1], ('Content-Length', - str(len(body)))) - class FunctionalTests(unittest.TestCase): def setUp(self): from myproject import main diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index c05ee41ad..a3f62058b 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -348,26 +348,6 @@ code's integration with the rest of :app:`Pyramid`. See also :ref:`including_configuration` -Let's demonstrate this by showing an integration test for a view. - -Given the following view definition, which assumes that your application's -:term:`package` name is ``myproject``, and within that :term:`package` there -exists a module ``views``, which in turn contains a :term:`view` function named -``my_view``: - - .. literalinclude:: MyProject/myproject/views.py - :linenos: - :lines: 1-6 - :language: python - -You'd then create a ``tests`` module within your ``myproject`` package, -containing the following test code: - - .. literalinclude:: MyProject/myproject/tests.py - :linenos: - :pyobject: ViewIntegrationTests - :language: python - Writing unit tests that use the :class:`~pyramid.config.Configurator` API to set up the right "mock" registrations is often preferred to creating integration tests. Unit tests will run faster (because they do less for each @@ -388,22 +368,53 @@ package, which provides APIs for invoking HTTP(S) requests to your application. Regardless of which testing :term:`package` you use, ensure to add a ``tests_require`` dependency on that package to your application's -``setup.py`` file: +``setup.py`` file. Using the project ``MyProject`` generated by the starter +scaffold as described in :doc:`project`, we would insert the following code immediately following the +``requires`` block in the file ``MyProject/setup.py``. - .. literalinclude:: MyProject/setup.py - :linenos: - :emphasize-lines: 26-28,48 - :language: python +.. code-block:: ini + :linenos: + :lineno-start: 11 + :emphasize-lines: 8- + + requires = [ + 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'waitress', + ] + + test_requires = [ + 'webtest', + ] + +Remember to change the dependency. + +.. code-block:: ini + :linenos: + :lineno-start: 39 + :emphasize-lines: 2 + + install_requires=requires, + tests_require=test_requires, + test_suite="myproject", + +As always, whenever you change your dependencies, make sure to run the +following command. + +.. code-block:: bash + + $VENV/bin/python setup.py develop -Let us assume your :term:`package` is named ``myproject`` which contains a -``views`` module, which in turn contains a :term:`view` function ``my_view`` -that returns a HTML body when the root URL is invoked: +In your ``MyPackage`` project, your :term:`package` is named ``myproject`` +which contains a ``views`` module, which in turn contains a :term:`view` +function ``my_view`` that returns an HTML body when the root URL is invoked: .. literalinclude:: MyProject/myproject/views.py :linenos: :language: python -Then the following example functional test demonstrates invoking the above +The following example functional test demonstrates invoking the above :term:`view`: .. literalinclude:: MyProject/myproject/tests.py @@ -414,9 +425,9 @@ Then the following example functional test demonstrates invoking the above When this test is run, each test method creates a "real" :term:`WSGI` application using the ``main`` function in your ``myproject.__init__`` module, using :term:`WebTest` to wrap that WSGI application. It assigns the result to -``self.testapp``. In the test named ``test_root``. The ``TestApp``'s ``GET`` +``self.testapp``. In the test named ``test_root``, the ``TestApp``'s ``GET`` method is used to invoke the root URL. Finally, an assertion is made that the -returned HTML contains the text ``MyProject``. +returned HTML contains the text ``Pyramid``. See the :term:`WebTest` documentation for further information about the methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 313ff3c28fbd3b784e4c87daf8ae8a4cf713262b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 16 Dec 2015 21:30:56 -0600 Subject: update docs to support explicit asset overrides --- docs/narr/assets.rst | 100 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 35 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 0e3f6af11..b28e6b5b3 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -380,11 +380,6 @@ assets using :meth:`~pyramid.config.Configurator.add_cache_buster`: 'mypackage:folder/static/', QueryStringConstantCacheBuster(str(int(time.time())))) -.. note:: - The trailing slash on the ``add_cache_buster`` call is important to - indicate that it is overriding every asset in the folder and not just a - file named ``static``. - Adding the cachebuster instructs :app:`Pyramid` to add the current time for a static asset to the query string in the asset's URL: @@ -451,12 +446,13 @@ the hash of the current commit: from an egg repository like PYPI, you can use this cachebuster to get the current commit's SHA1 to use as the cache bust token. """ - def __init__(self, param='x'): + def __init__(self, param='x', repo_path=None): super(GitCacheBuster, self).__init__(param=param) - here = os.path.dirname(os.path.abspath(__file__)) + if repo_path is None: + repo_path = os.path.dirname(os.path.abspath(__file__)) self.sha1 = subprocess.check_output( ['git', 'rev-parse', 'HEAD'], - cwd=here).strip() + cwd=repo_path).strip() def tokenize(self, pathspec): return self.sha1 @@ -469,10 +465,14 @@ well: import posixpath - def cache_buster(spec, subpath, kw): - base_subpath, ext = posixpath.splitext(subpath) - new_subpath = base_subpath + '-asdf' + ext - return new_subpath, kw + class PathConstantCacheBuster(object): + def __init__(self, token): + self.token = token + + def __call__(self, request, subpath, kw): + base_subpath, ext = posixpath.splitext(subpath) + new_subpath = base_subpath + self.token + ext + return new_subpath, kw The caveat with this approach is that modifying the path segment changes the file name, and thus must match what is actually on the @@ -532,29 +532,6 @@ The following code would set up a cachebuster: 'mypackage:static/', ManifestCacheBuster('myapp:static/manifest.json')) -A simpler approach is to use the -:class:`~pyramid.static.QueryStringConstantCacheBuster` to generate a global -token that will bust all of the assets at once. The advantage of this strategy -is that it is simple and by using the query string there doesn't need to be -any shared information between your application and the static assets. - -The following code would set up a cachebuster that just uses the time at -start up as a cachebust token: - -.. code-block:: python - :linenos: - - import time - from pyramid.static import QueryStringConstantCacheBuster - - config.add_static_view( - name='http://mycdn.example.com/', - path='mypackage:static') - - config.add_cache_buster( - 'mypackage:static/', - QueryStringConstantCacheBuster(str(int(time.time())))) - .. index:: single: static assets view @@ -834,3 +811,56 @@ when an override is used. As of Pyramid 1.6, it is also possible to override an asset by supplying an absolute path to a file or directory. This may be useful if the assets are not distributed as part of a Python package. + +Cache Busting and Asset Overrides +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Overriding static assets that are being hosted using +:meth:`pyramid.config.Configurator.add_static_view` can affect your cache +busting strategy when using any cache busters that are asset-aware such as +:class:`pyramid.static.ManifestCacheBuster`. What sets asset-aware cache +busters apart is that they have logic tied to specific assets. For example, +a manifest is only generated for a specific set of pre-defined assets. Now, +imagine you have overridden an asset defined in this manifest with a new, +unknown version. By default, the cache buster will be invoked for an asset +it has never seen before and will likely end up returning a cache busting +token for the original asset rather than the asset that will actually end up +being served! In order to get around this issue it's possible to attach a +different :class:`pyramid.interfaces.ICacheBuster` implementation to the +new assets. This would cause the original assets to be served by their +manifest, and the new assets served by their own cache buster. To do this, +:meth:`pyramid.config.Configurator.add_cache_buster` supports an ``explicit`` +option. For example: + +.. code-block:: python + :linenos: + + from pyramid.static import ManifestCacheBuster + + # define a static view for myapp:static assets + config.add_static_view('static', 'myapp:static') + + # setup a cache buster for your app based on the myapp:static assets + my_cb = ManifestCacheBuster('myapp:static/manifest.json') + config.add_cache_buster('myapp:static', my_cb) + + # override an asset + config.override_asset( + to_override='myapp:static/background.png', + override_with='theme:static/background.png') + + # override the cache buster for theme:static assets + theme_cb = ManifestCacheBuster('theme:static/manifest.json') + config.add_cache_buster('theme:static', theme_cb, explicit=True) + +In the above example there is a default cache buster, ``my_cb`` for all assets +served from the ``myapp:static`` folder. This would also affect +``theme:static/background.png`` when generating URLs via +``request.static_url('myapp:static/background.png')``. + +The ``theme_cb`` is defined explicitly for any assets loaded from the +``theme:static`` folder. Explicit cache busters have priority and thus +``theme_cb`` would be invoked for +``request.static_url('myapp:static/background.png')`` but ``my_cb`` would be +used for any other assets like +``request.static_url('myapp:static/favicon.ico')``. -- cgit v1.2.3 From 897d1deeab710233565f97d216e4d112b2a466e3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 17 Dec 2015 20:52:19 -0600 Subject: grammar updates from stevepiercy --- docs/narr/assets.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index b28e6b5b3..054c58247 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -557,7 +557,7 @@ use some of the following options to get started: * Configure your asset pipeline to rewrite URL references inline in CSS and JavaScript. This is the best approach because then the files - may be hosted by :app:`Pyramid` or an external CDN without haven't to + may be hosted by :app:`Pyramid` or an external CDN without having to change anything. They really are static. * Templatize JS and CSS, and call ``request.static_url()`` inside their @@ -825,7 +825,7 @@ imagine you have overridden an asset defined in this manifest with a new, unknown version. By default, the cache buster will be invoked for an asset it has never seen before and will likely end up returning a cache busting token for the original asset rather than the asset that will actually end up -being served! In order to get around this issue it's possible to attach a +being served! In order to get around this issue, it's possible to attach a different :class:`pyramid.interfaces.ICacheBuster` implementation to the new assets. This would cause the original assets to be served by their manifest, and the new assets served by their own cache buster. To do this, @@ -853,14 +853,14 @@ option. For example: theme_cb = ManifestCacheBuster('theme:static/manifest.json') config.add_cache_buster('theme:static', theme_cb, explicit=True) -In the above example there is a default cache buster, ``my_cb`` for all assets -served from the ``myapp:static`` folder. This would also affect +In the above example there is a default cache buster, ``my_cb``, for all +assets served from the ``myapp:static`` folder. This would also affect ``theme:static/background.png`` when generating URLs via ``request.static_url('myapp:static/background.png')``. The ``theme_cb`` is defined explicitly for any assets loaded from the ``theme:static`` folder. Explicit cache busters have priority and thus ``theme_cb`` would be invoked for -``request.static_url('myapp:static/background.png')`` but ``my_cb`` would be -used for any other assets like +``request.static_url('myapp:static/background.png')``, but ``my_cb`` would +be used for any other assets like ``request.static_url('myapp:static/favicon.ico')``. -- cgit v1.2.3 From 5ff3d2dfdbf936d115e3486696401ad7dbffedc3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 21 Dec 2015 01:24:34 -0800 Subject: - add p* scripts - add links to p* scripts - add a blank line to keep indices and labels better visually related to the subsequent heading --- docs/narr/commandline.rst | 33 +++++++++++++++++++++++++++++++++ docs/narr/project.rst | 6 ++++++ 2 files changed, 39 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index eb79dffb6..34b12e1e9 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -6,6 +6,7 @@ Command-Line Pyramid Your :app:`Pyramid` application can be controlled and inspected using a variety of command-line utilities. These utilities are documented in this chapter. + .. index:: pair: matching views; printing single: pviews @@ -15,6 +16,8 @@ of command-line utilities. These utilities are documented in this chapter. Displaying Matching Views for a Given URL ----------------------------------------- +.. seealso:: See also the output of :ref:`pviews --help `. + For a big application with several views, it can be hard to keep the view configuration details in your head, even if you defined all the views yourself. You can use the ``pviews`` command in a terminal window to print a summary of @@ -114,6 +117,8 @@ found* message. The Interactive Shell --------------------- +.. seealso:: See also the output of :ref:`pshell --help `. + Once you've installed your program for development using ``setup.py develop``, you can use an interactive Python shell to execute expressions in a Python environment exactly like the one that will be used when your application runs @@ -179,6 +184,7 @@ hash after the filename: Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). + .. index:: pair: pshell; extending @@ -261,6 +267,7 @@ request is configured to generate urls from the host >>> request.route_url('home') 'https://www.example.com/' + .. _ipython_or_bpython: Alternative Shells @@ -317,6 +324,7 @@ arguments, ``env`` and ``help``, which would look like this: ``ipython`` and ``bpython`` have been moved into their respective packages ``pyramid_ipython`` and ``pyramid_bpython``. + Setting a Default Shell ~~~~~~~~~~~~~~~~~~~~~~~ @@ -331,6 +339,7 @@ specify a list of preferred shells. .. versionadded:: 1.6 + .. index:: pair: routes; printing single: proutes @@ -340,6 +349,8 @@ specify a list of preferred shells. Displaying All Application Routes --------------------------------- +.. seealso:: See also the output of :ref:`proutes --help `. + You can use the ``proutes`` command in a terminal window to print a summary of routes related to your application. Much like the ``pshell`` command (see :ref:`interactive_shell`), the ``proutes`` command accepts one argument with @@ -421,6 +432,8 @@ include. The current available formats are ``name``, ``pattern``, ``view``, and Displaying "Tweens" ------------------- +.. seealso:: See also the output of :ref:`ptweens --help `. + A :term:`tween` is a bit of code that sits between the main Pyramid application request handler and the WSGI application which calls it. A user can get a representation of both the implicit tween ordering (the ordering specified by @@ -497,6 +510,7 @@ used: See :ref:`registering_tweens` for more information about tweens. + .. index:: single: invoking a request single: prequest @@ -506,6 +520,8 @@ See :ref:`registering_tweens` for more information about tweens. Invoking a Request ------------------ +.. seealso:: See also the output of :ref:`prequest --help `. + You can use the ``prequest`` command-line utility to send a request to your application and see the response body without starting a server. @@ -555,6 +571,7 @@ of the ``prequest`` process is used as the ``POST`` body:: $ $VENV/bin/prequest -mPOST development.ini / < somefile + Using Custom Arguments to Python when Running ``p*`` Scripts ------------------------------------------------------------ @@ -566,11 +583,22 @@ Python interpreter at runtime. For example:: python -3 -m pyramid.scripts.pserve development.ini + +.. index:: + single: pdistreport + single: distributions, showing installed + single: showing installed distributions + +.. _showing_distributions: + Showing All Installed Distributions and Their Versions ------------------------------------------------------ .. versionadded:: 1.5 +.. seealso:: See also the output of :ref:`pdistreport --help + `. + You can use the ``pdistreport`` command to show the :app:`Pyramid` version in use, the Python version in use, and all installed versions of Python distributions in your Python environment:: @@ -590,6 +618,7 @@ pastebin when you are having problems and need someone with more familiarity with Python packaging and distribution than you have to look at your environment. + .. _writing_a_script: Writing a Script @@ -702,6 +731,7 @@ The above example specifies the ``another`` ``app``, ``pipeline``, or object present in the ``env`` dictionary returned by :func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router`. + Changing the Request ~~~~~~~~~~~~~~~~~~~~ @@ -742,6 +772,7 @@ Now you can readily use Pyramid's APIs for generating URLs: env['request'].route_url('verify', code='1337') # will return 'https://example.com/prefix/verify/1337' + Cleanup ~~~~~~~ @@ -757,6 +788,7 @@ callback: env['closer']() + Setting Up Logging ~~~~~~~~~~~~~~~~~~ @@ -773,6 +805,7 @@ use the following command: See :ref:`logging_chapter` for more information on logging within :app:`Pyramid`. + .. index:: single: console script diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4785b60c4..5103bb6b8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -53,15 +53,19 @@ The included scaffolds are these: ``alchemy`` URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` + .. index:: single: creating a project single: project + single: pcreate .. _creating_a_project: Creating the Project -------------------- +.. seealso:: See also the output of :ref:`pcreate --help `. + In :ref:`installing_chapter`, you created a virtual Python environment via the ``virtualenv`` command. To start a :app:`Pyramid` :term:`project`, use the ``pcreate`` command installed within the virtualenv. We'll choose the @@ -262,6 +266,8 @@ single sample test exists. Running the Project Application ------------------------------- +.. seealso:: See also the output of :ref:`pserve --help `. + Once a project is installed for development, you can run the application it represents using the ``pserve`` command against the generated configuration file. In our case, this file is named ``development.ini``. -- cgit v1.2.3 From 2901e968390f70b4bfa777dd4348dc9d3eb6210c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 3 Jan 2016 00:22:44 -0600 Subject: add a note about serving cache busted assets --- docs/narr/assets.rst | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 054c58247..58f547fc9 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -532,6 +532,14 @@ The following code would set up a cachebuster: 'mypackage:static/', ManifestCacheBuster('myapp:static/manifest.json')) +It's important to note that the cache buster only handles generating +cache-busted URLs for static assets. It does **NOT** provide any solutions for +serving those assets. For example, if you generated a URL for +``css/main-678b7c80.css`` then that URL needs to be valid either by +configuring ``add_static_view`` properly to point to the location of the files +or some other mechanism such as the files existing on your CDN or rewriting +the incoming URL to remove the cache bust tokens. + .. index:: single: static assets view -- cgit v1.2.3 From 1f7305442e2aa824af4223df6b844cc988034492 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 13 Jan 2016 09:22:50 -0800 Subject: add python 3.5 --- docs/narr/install.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 26d458727..164442262 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -15,8 +15,8 @@ You will need `Python `_ version 2.6 or better to run .. sidebar:: Python Versions As of this writing, :app:`Pyramid` has been tested under Python 2.6, Python - 2.7, Python 3.2, Python 3.3, Python 3.4, PyPy, and PyPy3. :app:`Pyramid` - does not run under any version of Python before 2.6. + 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, PyPy, and PyPy3. + :app:`Pyramid` does not run under any version of Python before 2.6. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run -- cgit v1.2.3 From 384007c4e6e1c0c397b9c643c8c34bdf0ddf4b07 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 13 Jan 2016 13:24:26 -0800 Subject: update for python 3.5 --- docs/narr/install.rst | 2 +- docs/narr/introduction.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 164442262..381e325df 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -46,7 +46,7 @@ Alternatively, you can use the `homebrew `_ package manager. # for python 2.7 $ brew install python - # for python 3.4 + # for python 3.5 $ brew install python3 If you use an installer for your Python, then you can skip to the section diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7906dd85d..40f465b0a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -861,10 +861,10 @@ tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, -PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid -add-ons are held to a similar testing standard. We still find bugs in Pyramid -and its official add-ons, but we've noticed we find a lot more of them while -working on other projects that don't have a good testing regime. +Python 3.5, PyPy, and PyPy3 after each commit to its GitHub repository. +Official Pyramid add-ons are held to a similar testing standard. We still find +bugs in Pyramid and its official add-ons, but we've noticed we find a lot more +of them while working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 34515f33b3e391dd1c0c727bf5ef4af586b57889 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 14 Jan 2016 02:55:04 -0800 Subject: Rename Cookbook to Pyramid Community Cookbook - use .rst intersphinx labels for pages instead of broken URLs --- docs/narr/advconfig.rst | 7 +++---- docs/narr/i18n.rst | 6 +++--- docs/narr/introduction.rst | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index ba9bd1352..bdcdf45a4 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -417,7 +417,6 @@ added in configuration execution order. More Information ---------------- -For more information, see the article `"A Whirlwind Tour of Advanced -Configuration Tactics" -`_ -in the Pyramid Cookbook. +For more information, see the article :ref:`A Whirlwind Tour of Advanced +Configuration Tactics ` in the Pyramid Community +Cookbook. diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index bb0bbe511..ecc48aa2b 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -666,9 +666,9 @@ can always use the more manual translation facility described in Mako Pyramid i18n Support ------------------------- -There exists a recipe within the :term:`Pyramid Cookbook` named ":ref:`Mako -Internationalization `" which explains how to add idiomatic -i18n support to :term:`Mako` templates. +There exists a recipe within the :term:`Pyramid Community Cookbook` named +:ref:`Mako Internationalization ` which explains how to add +idiomatic i18n support to :term:`Mako` templates. .. index:: single: localization deployment settings diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 40f465b0a..422db557e 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -892,8 +892,7 @@ also maintain a "cookbook" of recipes, which are usually demonstrations of common integration scenarios too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The Pyramid Cookbook at -http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. +Example: The :ref:`Pyramid Community Cookbook `. .. index:: single: Pylons Project -- cgit v1.2.3 From d49c69250b406597a4796d158cf6540469ade414 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 20 Jan 2016 00:18:41 -0800 Subject: Do not use trailing . on versionadded rst directive. It automatically adds a . --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 6aa1a99c2..7ff119b53 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -262,7 +262,7 @@ already constructed a :term:`configurator`, it can also be registered via the Adding Methods or Properties to a Request Object ------------------------------------------------ -.. versionadded:: 1.4. +.. versionadded:: 1.4 Since each Pyramid application can only have one :term:`request` factory, :ref:`changing the request factory ` is not that -- cgit v1.2.3 From 4064028cadc63ed1aceb14e6c88827b88b12f839 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 20 Jan 2016 00:38:09 -0800 Subject: Update docs to reflect dropping Python 3.2 support --- docs/narr/install.rst | 4 ++-- docs/narr/introduction.rst | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 381e325df..c4e3e2c5f 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -15,8 +15,8 @@ You will need `Python `_ version 2.6 or better to run .. sidebar:: Python Versions As of this writing, :app:`Pyramid` has been tested under Python 2.6, Python - 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, PyPy, and PyPy3. - :app:`Pyramid` does not run under any version of Python before 2.6. + 2.7, Python 3.3, Python 3.4, Python 3.5, PyPy, and PyPy3. :app:`Pyramid` + does not run under any version of Python before 2.6. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 422db557e..8db52dc21 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -860,11 +860,11 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, -Python 3.5, PyPy, and PyPy3 after each commit to its GitHub repository. -Official Pyramid add-ons are held to a similar testing standard. We still find -bugs in Pyramid and its official add-ons, but we've noticed we find a lot more -of them while working on other projects that don't have a good testing regime. +Jenkins tool on Python 2.6, Python 2.7, Python 3.3, Python 3.4, Python 3.5, +PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid +add-ons are held to a similar testing standard. We still find bugs in Pyramid +and its official add-ons, but we've noticed we find a lot more of them while +working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 5adb45a47e4ebfff5d2ea28833ef29a7f3ddbb25 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 22 Jan 2016 15:15:34 -0800 Subject: Add Python support policy (see https://github.com/Pylons/pyramid/pull/2256#issuecomment-174029882) --- docs/narr/upgrading.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index db9b5e090..cacfba92a 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -75,6 +75,27 @@ changes are noted in the :ref:`changelog`, so it's possible to know that you should change older spellings to newer ones to ensure that people reading your code can find the APIs you're using in the Pyramid docs. + +Python support policy +~~~~~~~~~~~~~~~~~~~~~ + +At the time of a Pyramid version release, each supports all versions of Python +through the end of their lifespans. The end-of-life for a given version of +Python is when security updates are no longer released. + +- `Python 3.2 Lifespan `_ + ends February 2016. +- `Python 3.3 Lifespan `_ + ends September 2017. +- `Python 3.4 Lifespan `_ TBD. +- `Python 3.5 Lifespan `_ TBD. +- `Python 3.6 Lifespan `_ + December 2021. + +To determine the Python support for a specific release of Pyramid, view its +``tox.ini`` file at the root of the repository's version. + + Consulting the change history ----------------------------- -- cgit v1.2.3 From 3cdd3cedb9a120228f5bb2c0a9d53c0017b55cd9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 24 Jan 2016 01:02:42 -0800 Subject: Use proper syntax in code samples to allow highlighting and avoid errors. See https://github.com/sphinx-doc/sphinx/issues/2264 --- docs/narr/project.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5103bb6b8..923fde436 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -447,7 +447,7 @@ commenting out a line. For example, instead of: :linenos: [app:main] - ... + # ... elided configuration pyramid.includes = pyramid_debugtoolbar @@ -457,7 +457,7 @@ Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: :linenos: [app:main] - ... + # ... elided configuration pyramid.includes = # pyramid_debugtoolbar -- cgit v1.2.3 From 22f221099e785cb763e9659da029933ca9fc11e6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 24 Jan 2016 01:10:13 -0800 Subject: Use proper syntax names in code samples to allow highlighting and avoid errors. See https://github.com/sphinx-doc/sphinx/issues/2264 --- docs/narr/webob.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index f18cf1dfb..cfcf532bc 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -269,7 +269,7 @@ to a :app:`Pyramid` application: When such a request reaches a view in your application, the ``request.json_body`` attribute will be available in the view callable body. -.. code-block:: javascript +.. code-block:: python @view_config(renderer='string') def aview(request): -- cgit v1.2.3 From 65bb52bafa5d44b378f01dfb47816a952bf93a66 Mon Sep 17 00:00:00 2001 From: Svintsov Dmitry Date: Sun, 24 Jan 2016 16:36:43 +0500 Subject: fix indent in docs --- docs/narr/install.rst | 4 ++-- docs/narr/subrequest.rst | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c4e3e2c5f..767b16fc0 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -292,7 +292,7 @@ After you've got your virtualenv installed, you may install :app:`Pyramid` itself using the following commands: .. parsed-literal:: - + $ $VENV/bin/easy_install "pyramid==\ |release|\ " The ``easy_install`` command will take longer than the previous ones to @@ -371,7 +371,7 @@ You can use Pyramid on Windows under Python 2 or 3. installed: .. parsed-literal:: - + c:\\env> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ " What Gets Installed diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 02ae14aa5..daa3cc43f 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -17,7 +17,7 @@ application. Here's an example application which uses a subrequest: .. code-block:: python - :linenos: + :linenos: from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -61,8 +61,8 @@ adapter when found and invoked via object: .. code-block:: python - :linenos: - :emphasize-lines: 11 + :linenos: + :emphasize-lines: 11 from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -106,8 +106,8 @@ exception, the exception will be raised to the caller of :term:`exception view` configured: .. code-block:: python - :linenos: - :emphasize-lines: 11-16 + :linenos: + :emphasize-lines: 11-16 from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -175,8 +175,8 @@ We can cause the subrequest to be run through the tween stack by passing :meth:`~pyramid.request.Request.invoke_subrequest`, like this: .. code-block:: python - :linenos: - :emphasize-lines: 7 + :linenos: + :emphasize-lines: 7 from wsgiref.simple_server import make_server from pyramid.config import Configurator -- cgit v1.2.3 From 8d212aac349c381fa20c2c8927acdaf4873e394e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 20 Feb 2016 19:09:34 -0800 Subject: fix links for babel and chameleon --- docs/narr/i18n.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index ecc48aa2b..839a48df4 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -585,10 +585,10 @@ Performing Date Formatting and Currency Formatting :app:`Pyramid` does not itself perform date and currency formatting for different locales. However, :term:`Babel` can help you do this via the :class:`babel.core.Locale` class. The `Babel documentation for this class -`_ -provides minimal information about how to perform date and currency related -locale operations. See :ref:`installing_babel` for information about how to -install Babel. +`_ provides +minimal information about how to perform date and currency related locale +operations. See :ref:`installing_babel` for information about how to install +Babel. The :class:`babel.core.Locale` class requires a :term:`locale name` as an argument to its constructor. You can use :app:`Pyramid` APIs to obtain the -- cgit v1.2.3 From 542f86ba5cd3e2eec18224b2e4eff88fe58b6f43 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 14:20:26 -0500 Subject: add a new docs section on invoking exception views --- docs/narr/subrequest.rst | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index daa3cc43f..ae1dd1b91 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -279,3 +279,49 @@ within a tween, because tweens already, by definition, have access to a function that will cause a subrequest (they are passed a ``handle`` function). It's fine to invoke :meth:`~pyramid.request.Request.invoke_subrequest` from within an event handler, however. + +Invoking an Exception View +-------------------------- + +.. versionadded:: 1.7 + +:app:`Pyramid` apps may define a :term:`exception views ` which +can handle any raised exceptions that escape from your code while processing +a request. By default, an unhandled exception will be caught by the `EXCVIEW` +:term:`tween` which will then lookup an exception view that can handle the +exception type, generating an appropriate error response. + +In :app:`Pyramid` 1.7 the :meth:`pyramid.request.Request.invoke_exception_view` +was introduced which allows a user to invoke an exception view while manually +handling an exception. This can be useful in a few different circumstances: + +- Manually handling an exception losing the current call stack / flow. + +- Handling exceptions outside of the context of the `EXCVIEW` tween. The + tween only covers certain parts of the request processing pipeline + (See :ref:`router chapter`) and there are some corner cases where an + exception can be raised which will still bubble up to middleware and possibly + to the web server where a generic ``500 Internal Server Error`` will be + returned to the client. + +Below is an example usage of +:meth:`pyramid.request.Request.invoke_exception_view`: + +.. code-block:: python + :linenos: + + def foo(request): + try: + some_func_that_errors() + return response + except Exception: + response = request.invoke_exception_view() + # there is no exception view for this exception, simply + # re-raise and let someone else handle it + if response is not None: + return response + else: + raise + +Please note that in most cases you do not need to write code like this an may +rely on the `EXCVIEW` tween to handle this for you. -- cgit v1.2.3 From 78cf75aef700f2db65d3dac379811c7f17eab1f7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 14:28:18 -0500 Subject: fix broken ref --- docs/narr/subrequest.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index ae1dd1b91..60972b156 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -299,7 +299,7 @@ handling an exception. This can be useful in a few different circumstances: - Handling exceptions outside of the context of the `EXCVIEW` tween. The tween only covers certain parts of the request processing pipeline - (See :ref:`router chapter`) and there are some corner cases where an + (See :ref:`router_chapter`) and there are some corner cases where an exception can be raised which will still bubble up to middleware and possibly to the web server where a generic ``500 Internal Server Error`` will be returned to the client. -- cgit v1.2.3 From 7175a51bec9491ff58a8ef3a94cc7804b476541d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 14:32:14 -0500 Subject: move comment closer to relevant logic --- docs/narr/subrequest.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 60972b156..a943dca5d 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -316,11 +316,11 @@ Below is an example usage of return response except Exception: response = request.invoke_exception_view() - # there is no exception view for this exception, simply - # re-raise and let someone else handle it if response is not None: return response else: + # there is no exception view for this exception, simply + # re-raise and let someone else handle it raise Please note that in most cases you do not need to write code like this an may -- cgit v1.2.3 From dc3f79537f6901cf81a25f557c8d7bad1fe4f111 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 14 Mar 2016 13:56:08 -0700 Subject: polish Invoking an Exception View docs - add index entry - minor grammar, syntax --- docs/narr/subrequest.rst | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index a943dca5d..7c847de50 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -280,28 +280,32 @@ function that will cause a subrequest (they are passed a ``handle`` function). It's fine to invoke :meth:`~pyramid.request.Request.invoke_subrequest` from within an event handler, however. + +.. index:: + pair: subrequest; exception view + Invoking an Exception View -------------------------- .. versionadded:: 1.7 -:app:`Pyramid` apps may define a :term:`exception views ` which +:app:`Pyramid` apps may define :term:`exception views ` which can handle any raised exceptions that escape from your code while processing -a request. By default, an unhandled exception will be caught by the `EXCVIEW` -:term:`tween` which will then lookup an exception view that can handle the +a request. By default an unhandled exception will be caught by the ``EXCVIEW`` +:term:`tween`, which will then lookup an exception view that can handle the exception type, generating an appropriate error response. In :app:`Pyramid` 1.7 the :meth:`pyramid.request.Request.invoke_exception_view` -was introduced which allows a user to invoke an exception view while manually +was introduced, allowing a user to invoke an exception view while manually handling an exception. This can be useful in a few different circumstances: -- Manually handling an exception losing the current call stack / flow. +- Manually handling an exception losing the current call stack or flow. -- Handling exceptions outside of the context of the `EXCVIEW` tween. The - tween only covers certain parts of the request processing pipeline - (See :ref:`router_chapter`) and there are some corner cases where an - exception can be raised which will still bubble up to middleware and possibly - to the web server where a generic ``500 Internal Server Error`` will be +- Handling exceptions outside of the context of the ``EXCVIEW`` tween. The + tween only covers certain parts of the request processing pipeline (See + :ref:`router_chapter`). There are also some corner cases where an exception + can be raised that will still bubble up to middleware, and possibly to the + web server in which case a generic ``500 Internal Server Error`` will be returned to the client. Below is an example usage of @@ -323,5 +327,5 @@ Below is an example usage of # re-raise and let someone else handle it raise -Please note that in most cases you do not need to write code like this an may -rely on the `EXCVIEW` tween to handle this for you. +Please note that in most cases you do not need to write code like this, and you +may rely on the ``EXCVIEW`` tween to handle this for you. -- cgit v1.2.3 From fdd1f8352fc341bc60e0b7d32dadd2b4109a2b41 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 22:08:04 -0500 Subject: first cut at documenting view derivers --- docs/narr/extconfig.rst | 1 + docs/narr/hooks.rst | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index fee8d0d3a..af7d0a349 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -259,6 +259,7 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.add_route_predicate` - :meth:`pyramid.config.Configurator.add_subscriber_predicate` - :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_permission` - :meth:`pyramid.config.Configurator.set_view_mapper` diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 7ff119b53..13daed1fc 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1547,3 +1547,143 @@ in every subscriber registration. It is not the responsibility of the predicate author to make every predicate make sense for every event type; it is the responsibility of the predicate consumer to use predicates that make sense for a particular event type registration. + +.. index:: + single: view derivers + +.. _view_derivers: + +View Derivers +------------- + +Every URL processed by :app:`Pyramid` is matched against a custom view +pipeline. See :ref:`router_chapter` for how this works. The view pipeline +itself is built from the user-supplied :term:`view callable` which is then +composed with :term:`view derivers `. A view deriver is a +composable element of the view pipeline which is used to wrap a view with +added functionality. View derivers are very similar to the ``decorator`` +argument to :meth:`pyramid.config.Configurator.add_view` except that they have +the option to execute for every view in the application. + +Built-in View Derivers +~~~~~~~~~~~~~~~~~~~~~~ + +There are several builtin view derivers that :app:`Pyramid` will automatically +apply to any view. They are defined in order from closest to furthest from +the user-defined :term:`view callable`: + +``mapped_view`` + + Applies the :term:`view mapper` defined by the ``mapper`` option or the + application's default view mapper to the :term:`view callable`. This + is always the closest deriver to the user-defined view and standardizes the + view pipeline interface to accept ``(context, request)`` from all previous + view derivers. + +``decorated_view`` + + Wraps the view with the decorators from the ``decorator`` option. + +``http_cached_view`` + + Applies cache control headers to the response defined by the ``http_cache`` + option. This element is a noop if the ``pyramid.prevent_http_cache`` setting + is enabled or the ``http_cache`` option is ``None``. + +``owrapped_view`` + + Invokes the wrapped view defined by the ``wrapper`` option. + +``secured_view`` + + Enforce the ``permission`` defined on the view. This element is a noop if + no permission is defined. Note there will always be a permission defined + if a default permission was assigned via + :meth:`pyramid.config.Configurator.set_default_permission`. + +``authdebug_view`` + + Used to output useful debugging information when + ``pyramid.debug_authorization`` is enabled. This element is a noop otherwise. + +Custom View Derivers +~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.7 + +It is possible to define custom view derivers which will affect all views in +an application. There are many uses for this but most will likely be centered +around monitoring and security. In order to register a custom +:term:`view deriver` you should create a callable that conforms to the +:class:`pyramid.interfaces.IViewDeriver` interface. For example, below +is a callable that can provide timing information for the view pipeline: + +.. code-block:: python + :linenos: + + import time + + def timing_view(view, info): + def wrapper_view(context, request): + start = time.time() + response = view(context, request) + end = time.time() + response.headers['X-View-Performance'] = '%.3f' % (end - start,) + return wrapper_view + + config.add_view_deriver('timing_view', timing_view) + +View derivers are unique in that they have access to most of the options +passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what +to do and they have a chance to affect every view in the application. + +Let's look at one more example which will protect views by requiring a CSRF +token unless ``disable_csrf=True`` is passed to the view: + +.. code-block:: python + :linenos: + + from pyramid.session import check_csrf_token + + def require_csrf_view(view, info): + wrapper_view = view + if not info.options.get('disable_csrf', False): + def wrapper_view(context, request): + if request.method == 'POST': + check_csrf_token(request) + return view(context, request) + return wrapper_view + + require_csrf_view.options = ('disable_csrf',) + + config.add_view_deriver('require_csrf_view', require_csrf_view) + + def myview(request): + return 'protected' + + def my_unprotected_view(request): + return 'unprotected' + + config.add_view(myview, name='safe', renderer='string') + config.add_view(my_unprotected_, name='unsafe', disable_csrf=True, renderer='string') + +Navigating to ``/safe`` with a POST request will then fail when the call to +:func:`pyramid.session.check_csrf_token` raises a +:class:`pyramid.exceptions.BadCSRFToken` exception. However, ``/unsafe`` will +not error. + +Ordering View Derivers +~~~~~~~~~~~~~~~~~~~~~~ + +By default, every new view deriver is added between the ``decorated_view`` +and ``mapped_view`` built-in derivers. It is possible to customize this +ordering using the ``over`` and ``under`` options. Each option can use the +names of other view derivers in order to specify an ordering. There should +rarely be a reason to worry about the ordering of the derivers. + +It is not possible to add a deriver OVER the ``mapped_view`` as the +:term:`view mapper` is intimately tied to the signature of the user-defined +:term:`view callable`. If you simply need to know what the original view +callable was, it can be found as ``info.original_view`` on the provided +:class:`pyramid.interfaces.IViewDeriverInfo` object passed to every view +deriver. -- cgit v1.2.3 From 64bf7eec9b868fbc113341c7f5675c063aea002b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 22:35:19 -0500 Subject: use the implicit name in the doc examples --- docs/narr/hooks.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 13daed1fc..3f66f4988 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1631,7 +1631,7 @@ is a callable that can provide timing information for the view pipeline: response.headers['X-View-Performance'] = '%.3f' % (end - start,) return wrapper_view - config.add_view_deriver('timing_view', timing_view) + config.add_view_deriver(timing_view) View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what @@ -1656,7 +1656,7 @@ token unless ``disable_csrf=True`` is passed to the view: require_csrf_view.options = ('disable_csrf',) - config.add_view_deriver('require_csrf_view', require_csrf_view) + config.add_view_deriver(require_csrf_view) def myview(request): return 'protected' -- cgit v1.2.3 From a0945399b24fb38607107a55b12b7997723de2a0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 23:25:10 -0500 Subject: do not guess at the name of the view deriver without further discussion --- docs/narr/hooks.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3f66f4988..e3843cfbd 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1631,7 +1631,7 @@ is a callable that can provide timing information for the view pipeline: response.headers['X-View-Performance'] = '%.3f' % (end - start,) return wrapper_view - config.add_view_deriver(timing_view) + config.add_view_deriver(timing_view, 'timing view') View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what @@ -1656,7 +1656,7 @@ token unless ``disable_csrf=True`` is passed to the view: require_csrf_view.options = ('disable_csrf',) - config.add_view_deriver(require_csrf_view) + config.add_view_deriver(require_csrf_view, 'require_csrf_view') def myview(request): return 'protected' -- cgit v1.2.3 From 35e632635b1b4e0a767024689d69d9469ae98c0f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Mar 2016 23:28:15 -0500 Subject: add a docstring for add_view_deriver and expose the method to the api docs --- docs/narr/hooks.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index e3843cfbd..a5a03ef95 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1580,6 +1580,10 @@ the user-defined :term:`view callable`: view pipeline interface to accept ``(context, request)`` from all previous view derivers. +``rendered_view`` + + Adapts the result of :term:`view callable` into a :term:`response` object. + ``decorated_view`` Wraps the view with the decorators from the ``decorator`` option. @@ -1615,8 +1619,10 @@ It is possible to define custom view derivers which will affect all views in an application. There are many uses for this but most will likely be centered around monitoring and security. In order to register a custom :term:`view deriver` you should create a callable that conforms to the -:class:`pyramid.interfaces.IViewDeriver` interface. For example, below -is a callable that can provide timing information for the view pipeline: +:class:`pyramid.interfaces.IViewDeriver` interface and then register it with +your application using :meth:`pyramid.config.Configurator.add_view_deriver`. +For example, below is a callable that can provide timing information for the +view pipeline: .. code-block:: python :linenos: @@ -1676,7 +1682,7 @@ Ordering View Derivers ~~~~~~~~~~~~~~~~~~~~~~ By default, every new view deriver is added between the ``decorated_view`` -and ``mapped_view`` built-in derivers. It is possible to customize this +and ``rendered_view`` built-in derivers. It is possible to customize this ordering using the ``over`` and ``under`` options. Each option can use the names of other view derivers in order to specify an ordering. There should rarely be a reason to worry about the ordering of the derivers. -- cgit v1.2.3 From a116948ffe14449ac6ef29145b62eb2976130d83 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 17 Mar 2016 01:24:21 -0500 Subject: fix deriver docs to explain ordering issues --- docs/narr/hooks.rst | 81 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 31 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a5a03ef95..4a1233244 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1556,6 +1556,8 @@ for a particular event type registration. View Derivers ------------- +.. versionadded:: 1.7 + Every URL processed by :app:`Pyramid` is matched against a custom view pipeline. See :ref:`router_chapter` for how this works. The view pipeline itself is built from the user-supplied :term:`view callable` which is then @@ -1565,28 +1567,33 @@ added functionality. View derivers are very similar to the ``decorator`` argument to :meth:`pyramid.config.Configurator.add_view` except that they have the option to execute for every view in the application. +It is helpful to think of a :term:`view deriver` as middleware for views. +Unlike tweens or WSGI middleware which are scoped to the application itself, +a view deriver is invoked once per view in the application and can use +configuration options from the view to customize its behavior. + Built-in View Derivers ~~~~~~~~~~~~~~~~~~~~~~ There are several builtin view derivers that :app:`Pyramid` will automatically -apply to any view. They are defined in order from closest to furthest from +apply to any view. Below they are defined in order from furthest to closest to the user-defined :term:`view callable`: -``mapped_view`` +``authdebug_view`` - Applies the :term:`view mapper` defined by the ``mapper`` option or the - application's default view mapper to the :term:`view callable`. This - is always the closest deriver to the user-defined view and standardizes the - view pipeline interface to accept ``(context, request)`` from all previous - view derivers. + Used to output useful debugging information when + ``pyramid.debug_authorization`` is enabled. This element is a noop otherwise. -``rendered_view`` +``secured_view`` - Adapts the result of :term:`view callable` into a :term:`response` object. + Enforce the ``permission`` defined on the view. This element is a noop if + no permission is defined. Note there will always be a permission defined + if a default permission was assigned via + :meth:`pyramid.config.Configurator.set_default_permission`. -``decorated_view`` +``owrapped_view`` - Wraps the view with the decorators from the ``decorator`` option. + Invokes the wrapped view defined by the ``wrapper`` option. ``http_cached_view`` @@ -1594,27 +1601,26 @@ the user-defined :term:`view callable`: option. This element is a noop if the ``pyramid.prevent_http_cache`` setting is enabled or the ``http_cache`` option is ``None``. -``owrapped_view`` +``decorated_view`` - Invokes the wrapped view defined by the ``wrapper`` option. + Wraps the view with the decorators from the ``decorator`` option. -``secured_view`` +``rendered_view`` - Enforce the ``permission`` defined on the view. This element is a noop if - no permission is defined. Note there will always be a permission defined - if a default permission was assigned via - :meth:`pyramid.config.Configurator.set_default_permission`. + Adapts the result of the :term:`view callable` into a :term:`response` + object. Below this point the result may be any Python object. -``authdebug_view`` +``mapped_view`` - Used to output useful debugging information when - ``pyramid.debug_authorization`` is enabled. This element is a noop otherwise. + Applies the :term:`view mapper` defined by the ``mapper`` option or the + application's default view mapper to the :term:`view callable`. This + is always the closest deriver to the user-defined view and standardizes the + view pipeline interface to accept ``(context, request)`` from all previous + view derivers. Custom View Derivers ~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.7 - It is possible to define custom view derivers which will affect all views in an application. There are many uses for this but most will likely be centered around monitoring and security. In order to register a custom @@ -1649,6 +1655,7 @@ token unless ``disable_csrf=True`` is passed to the view: .. code-block:: python :linenos: + from pyramid.response import Response from pyramid.session import check_csrf_token def require_csrf_view(view, info): @@ -1664,14 +1671,14 @@ token unless ``disable_csrf=True`` is passed to the view: config.add_view_deriver(require_csrf_view, 'require_csrf_view') - def myview(request): - return 'protected' + def protected_view(request): + return Response('protected') - def my_unprotected_view(request): - return 'unprotected' + def unprotected_view(request): + return Response('unprotected') - config.add_view(myview, name='safe', renderer='string') - config.add_view(my_unprotected_, name='unsafe', disable_csrf=True, renderer='string') + config.add_view(protected_view, name='safe') + config.add_view(unprotected_view, name='unsafe', disable_csrf=True) Navigating to ``/safe`` with a POST request will then fail when the call to :func:`pyramid.session.check_csrf_token` raises a @@ -1685,11 +1692,23 @@ By default, every new view deriver is added between the ``decorated_view`` and ``rendered_view`` built-in derivers. It is possible to customize this ordering using the ``over`` and ``under`` options. Each option can use the names of other view derivers in order to specify an ordering. There should -rarely be a reason to worry about the ordering of the derivers. +rarely be a reason to worry about the ordering of the derivers. Both ``over`` +and ``under`` may also be iterables of constraints. For either option, if one +or more constraints was defined, at least one must be satisfied or a +:class:`pyramid.exceptions.ConfigurationError` will be raised. This may be +used to define fallback constraints if another deriver is missing. -It is not possible to add a deriver OVER the ``mapped_view`` as the +It is not possible to add a view deriver under the ``mapped_view`` as the :term:`view mapper` is intimately tied to the signature of the user-defined :term:`view callable`. If you simply need to know what the original view callable was, it can be found as ``info.original_view`` on the provided :class:`pyramid.interfaces.IViewDeriverInfo` object passed to every view deriver. + +.. warning:: + + Any view derivers defined ``under`` the ``rendered_view`` are not + guaranteed to receive a valid response object. Rather they will receive the + result from the :term:`view mapper` which is likely the original response + returned from the view. This is possibly a dictionary for a renderer but it + may be any Python object that may be adapted into a response. -- cgit v1.2.3 From 6fb44f451abb657716ae0066ed70af66060ef3b8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 21 Mar 2016 04:32:21 -0700 Subject: polish view derivers docs, minor grammar --- docs/narr/hooks.rst | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4a1233244..a32e94d1a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1548,6 +1548,7 @@ predicate author to make every predicate make sense for every event type; it is the responsibility of the predicate consumer to use predicates that make sense for a particular event type registration. + .. index:: single: view derivers @@ -1560,35 +1561,36 @@ View Derivers Every URL processed by :app:`Pyramid` is matched against a custom view pipeline. See :ref:`router_chapter` for how this works. The view pipeline -itself is built from the user-supplied :term:`view callable` which is then +itself is built from the user-supplied :term:`view callable`, which is then composed with :term:`view derivers `. A view deriver is a composable element of the view pipeline which is used to wrap a view with added functionality. View derivers are very similar to the ``decorator`` -argument to :meth:`pyramid.config.Configurator.add_view` except that they have +argument to :meth:`pyramid.config.Configurator.add_view`, except that they have the option to execute for every view in the application. It is helpful to think of a :term:`view deriver` as middleware for views. Unlike tweens or WSGI middleware which are scoped to the application itself, -a view deriver is invoked once per view in the application and can use +a view deriver is invoked once per view in the application, and can use configuration options from the view to customize its behavior. Built-in View Derivers ~~~~~~~~~~~~~~~~~~~~~~ -There are several builtin view derivers that :app:`Pyramid` will automatically +There are several built-in view derivers that :app:`Pyramid` will automatically apply to any view. Below they are defined in order from furthest to closest to the user-defined :term:`view callable`: ``authdebug_view`` Used to output useful debugging information when - ``pyramid.debug_authorization`` is enabled. This element is a noop otherwise. + ``pyramid.debug_authorization`` is enabled. This element is a no-op + otherwise. ``secured_view`` - Enforce the ``permission`` defined on the view. This element is a noop if - no permission is defined. Note there will always be a permission defined - if a default permission was assigned via + Enforce the ``permission`` defined on the view. This element is a no-op if no + permission is defined. Note there will always be a permission defined if a + default permission was assigned via :meth:`pyramid.config.Configurator.set_default_permission`. ``owrapped_view`` @@ -1598,7 +1600,7 @@ the user-defined :term:`view callable`: ``http_cached_view`` Applies cache control headers to the response defined by the ``http_cache`` - option. This element is a noop if the ``pyramid.prevent_http_cache`` setting + option. This element is a no-op if the ``pyramid.prevent_http_cache`` setting is enabled or the ``http_cache`` option is ``None``. ``decorated_view`` @@ -1621,11 +1623,11 @@ the user-defined :term:`view callable`: Custom View Derivers ~~~~~~~~~~~~~~~~~~~~ -It is possible to define custom view derivers which will affect all views in -an application. There are many uses for this but most will likely be centered -around monitoring and security. In order to register a custom -:term:`view deriver` you should create a callable that conforms to the -:class:`pyramid.interfaces.IViewDeriver` interface and then register it with +It is possible to define custom view derivers which will affect all views in an +application. There are many uses for this, but most will likely be centered +around monitoring and security. In order to register a custom :term:`view +deriver`, you should create a callable that conforms to the +:class:`pyramid.interfaces.IViewDeriver` interface, and then register it with your application using :meth:`pyramid.config.Configurator.add_view_deriver`. For example, below is a callable that can provide timing information for the view pipeline: @@ -1647,7 +1649,7 @@ view pipeline: View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what -to do and they have a chance to affect every view in the application. +to do, and they have a chance to affect every view in the application. Let's look at one more example which will protect views by requiring a CSRF token unless ``disable_csrf=True`` is passed to the view: @@ -1688,15 +1690,16 @@ not error. Ordering View Derivers ~~~~~~~~~~~~~~~~~~~~~~ -By default, every new view deriver is added between the ``decorated_view`` -and ``rendered_view`` built-in derivers. It is possible to customize this -ordering using the ``over`` and ``under`` options. Each option can use the -names of other view derivers in order to specify an ordering. There should -rarely be a reason to worry about the ordering of the derivers. Both ``over`` -and ``under`` may also be iterables of constraints. For either option, if one -or more constraints was defined, at least one must be satisfied or a -:class:`pyramid.exceptions.ConfigurationError` will be raised. This may be -used to define fallback constraints if another deriver is missing. +By default, every new view deriver is added between the ``decorated_view`` and +``rendered_view`` built-in derivers. It is possible to customize this ordering +using the ``over`` and ``under`` options. Each option can use the names of +other view derivers in order to specify an ordering. There should rarely be a +reason to worry about the ordering of the derivers. + +Both ``over`` and ``under`` may also be iterables of constraints. For either +option, if one or more constraints was defined, at least one must be satisfied, +else a :class:`pyramid.exceptions.ConfigurationError` will be raised. This may +be used to define fallback constraints if another deriver is missing. It is not possible to add a view deriver under the ``mapped_view`` as the :term:`view mapper` is intimately tied to the signature of the user-defined -- cgit v1.2.3 From 44bbbc32b607b043e708a625c4b1756db8919bdd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Apr 2016 02:17:59 -0700 Subject: - replace easy_install with pip - bump Python version to 3.5 or generalize to Python 3 - rewrite seealso's - use ps1con lexer for windows powershell console - add hyperlink targets --- docs/narr/install.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 767b16fc0..4a2f228a3 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -29,6 +29,9 @@ Some :app:`Pyramid` dependencies may attempt to build C extensions for performance speedups. If a compiler or Python headers are unavailable the dependency will fall back to using pure Python instead. + +.. _for-mac-os-x-users: + For Mac OS X Users ~~~~~~~~~~~~~~~~~~ @@ -52,6 +55,9 @@ Alternatively, you can use the `homebrew `_ package manager. If you use an installer for your Python, then you can skip to the section :ref:`installing_unix`. + +.. _if-you-don-t-yet-have-a-python-interpreter-unix: + If You Don't Yet Have a Python Interpreter (UNIX) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From a3db3cab713fecc0c83c742cfe3f0736b1d94a92 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 7 Apr 2016 01:16:45 -0500 Subject: separate the viewderiver module and allow overriding the mapper --- docs/narr/hooks.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a32e94d1a..3a1ad8363 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1580,12 +1580,6 @@ There are several built-in view derivers that :app:`Pyramid` will automatically apply to any view. Below they are defined in order from furthest to closest to the user-defined :term:`view callable`: -``authdebug_view`` - - Used to output useful debugging information when - ``pyramid.debug_authorization`` is enabled. This element is a no-op - otherwise. - ``secured_view`` Enforce the ``permission`` defined on the view. This element is a no-op if no @@ -1593,6 +1587,9 @@ the user-defined :term:`view callable`: default permission was assigned via :meth:`pyramid.config.Configurator.set_default_permission`. + This element will also output useful debugging information when + ``pyramid.debug_authorization`` is enabled. + ``owrapped_view`` Invokes the wrapped view defined by the ``wrapper`` option. -- cgit v1.2.3 From c231d8174e811eec5a3faeafa5aee60757c6d31f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 8 Apr 2016 00:47:01 -0500 Subject: update constraints for derivers as well as docs --- docs/narr/hooks.rst | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3a1ad8363..2c3782387 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1617,6 +1617,14 @@ the user-defined :term:`view callable`: view pipeline interface to accept ``(context, request)`` from all previous view derivers. +.. warning:: + + Any view derivers defined ``under`` the ``rendered_view`` are not + guaranteed to receive a valid response object. Rather they will receive the + result from the :term:`view mapper` which is likely the original response + returned from the view. This is possibly a dictionary for a renderer but it + may be any Python object that may be adapted into a response. + Custom View Derivers ~~~~~~~~~~~~~~~~~~~~ @@ -1642,7 +1650,7 @@ view pipeline: response.headers['X-View-Performance'] = '%.3f' % (end - start,) return wrapper_view - config.add_view_deriver(timing_view, 'timing view') + config.add_view_deriver(timing_view) View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what @@ -1668,7 +1676,7 @@ token unless ``disable_csrf=True`` is passed to the view: require_csrf_view.options = ('disable_csrf',) - config.add_view_deriver(require_csrf_view, 'require_csrf_view') + config.add_view_deriver(require_csrf_view) def protected_view(request): return Response('protected') @@ -1691,13 +1699,19 @@ By default, every new view deriver is added between the ``decorated_view`` and ``rendered_view`` built-in derivers. It is possible to customize this ordering using the ``over`` and ``under`` options. Each option can use the names of other view derivers in order to specify an ordering. There should rarely be a -reason to worry about the ordering of the derivers. +reason to worry about the ordering of the derivers except when the deriver +depends on other operations in the view pipeline. Both ``over`` and ``under`` may also be iterables of constraints. For either option, if one or more constraints was defined, at least one must be satisfied, else a :class:`pyramid.exceptions.ConfigurationError` will be raised. This may be used to define fallback constraints if another deriver is missing. +Two sentinel values exist, :attr:`pyramid.viewderivers.INGRESS` and +:attr:`pyramid.viewderivers.VIEW`, which may be used when specifying +constraints at the edges of the view pipeline. For example, to add a deriver +at the start of the pipeline you may use ``under=INGRESS``. + It is not possible to add a view deriver under the ``mapped_view`` as the :term:`view mapper` is intimately tied to the signature of the user-defined :term:`view callable`. If you simply need to know what the original view @@ -1707,8 +1721,12 @@ deriver. .. warning:: - Any view derivers defined ``under`` the ``rendered_view`` are not - guaranteed to receive a valid response object. Rather they will receive the - result from the :term:`view mapper` which is likely the original response - returned from the view. This is possibly a dictionary for a renderer but it - may be any Python object that may be adapted into a response. + The default constraints for any view deriver are ``over='rendered_view'`` + and ``under='decorated_view'``. When escaping these constraints you must + take care to avoid cyclic dependencies between derivers. For example, if + you want to add a new view deriver before ``secured_view`` then + simply specifying ``over='secured_view'`` is not enough, because the + default is also under ``decorated view`` there will be an unsatisfiable + cycle. You must specify a valid ``under`` constraint as well, such as + ``under=INGRESS`` to fall between INGRESS and ``secured_view`` at the + beginning of the view pipeline. -- cgit v1.2.3 From 88c92b8f01ace15b57550cec2ab5c9127667f300 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 8 Apr 2016 02:18:51 -0700 Subject: Add pyramid_jinja2 example to i18n docs. Fixes #2437. --- docs/narr/i18n.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 839a48df4..b385eaf96 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -670,6 +670,21 @@ There exists a recipe within the :term:`Pyramid Community Cookbook` named :ref:`Mako Internationalization ` which explains how to add idiomatic i18n support to :term:`Mako` templates. + +.. index:: + single: Jinja2 i18n + +Jinja2 Pyramid i18n Support +--------------------------- + +The add-on `pyramid_jinja2 `_ +provides a scaffold with an example of how to use internationalization with +Jinja2 in Pyramid. See the documentation sections `Internalization (i18n) +`_ +and `Paster Template I18N +`_. + + .. index:: single: localization deployment settings single: default_locale_name -- cgit v1.2.3 From a624d56914ed9e10e3c0e8bb34a84700e78bcaf6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 10 Apr 2016 03:35:48 -0700 Subject: - update commandline.rst to use pip --- docs/narr/commandline.rst | 90 ++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 36 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 34b12e1e9..bc04f4c7a 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -119,7 +119,7 @@ The Interactive Shell .. seealso:: See also the output of :ref:`pshell --help `. -Once you've installed your program for development using ``setup.py develop``, +Once you've installed your program for development using ``pip install -e .``, you can use an interactive Python shell to execute expressions in a Python environment exactly like the one that will be used when your application runs "for real". To do so, use the ``pshell`` command line utility. @@ -294,7 +294,7 @@ You may use the ``--list-shells`` option to see the available shells. python If you want to use a shell that isn't supported out of the box, you can -introduce a new shell by registering an entry point in your setup.py: +introduce a new shell by registering an entry point in your ``setup.py``: .. code-block:: python @@ -840,12 +840,11 @@ following: distribution which creates a mapping between a script name and a dotted name representing the callable you added to your distribution. -- Run ``setup.py develop``, ``setup.py install``, or ``easy_install`` to get - your distribution reinstalled. When you reinstall your distribution, a file - representing the script that you named in the last step will be in the - ``bin`` directory of the virtualenv in which you installed the distribution. - It will be executable. Invoking it from a terminal will execute your - callable. +- Run ``pip install -e .`` or ``pip install .`` to get your distribution + reinstalled. When you reinstall your distribution, a file representing the + script that you named in the last step will be in the ``bin`` directory of + the virtualenv in which you installed the distribution. It will be + executable. Invoking it from a terminal will execute your callable. As an example, let's create some code that can be invoked by a console script that prints the deployment settings of a Pyramid application. To do so, we'll @@ -927,16 +926,22 @@ top-level directory, your ``setup.py`` file will look something like this: requires = ['pyramid', 'pyramid_debugtoolbar'] + testing_extras = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', # includes virtualenv + 'pytest-cov', + ] + setup(name='MyProject', version='0.0', description='My project', long_description=README + '\n\n' + CHANGES, classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], author='', author_email='', url='', @@ -945,20 +950,23 @@ top-level directory, your ``setup.py`` file will look something like this: include_package_data=True, zip_safe=False, install_requires=requires, - tests_require=requires, - test_suite="myproject", + extras_require={ + 'testing': testing_extras, + }, entry_points = """\ [paste.app_factory] main = myproject:main """, ) -We're going to change the setup.py file to add a ``[console_scripts]`` section -within the ``entry_points`` string. Within this section, you should specify a -``scriptname = dotted.path.to:yourfunction`` line. For example:: +We're going to change the ``setup.py`` file to add a ``[console_scripts]`` +section within the ``entry_points`` string. Within this section, you should +specify a ``scriptname = dotted.path.to:yourfunction`` line. For example: + +.. code-block:: ini - [console_scripts] - show_settings = myproject.scripts:settings_show + [console_scripts] + show_settings = myproject.scripts:settings_show The ``show_settings`` name will be the name of the script that is installed into ``bin``. The colon (``:``) between ``myproject.scripts`` and @@ -971,6 +979,7 @@ The result will be something like: .. code-block:: python :linenos: + :emphasize-lines: 43-44 import os @@ -984,16 +993,22 @@ The result will be something like: requires = ['pyramid', 'pyramid_debugtoolbar'] + testing_extras = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', # includes virtualenv + 'pytest-cov', + ] + setup(name='MyProject', version='0.0', description='My project', long_description=README + '\n\n' + CHANGES, classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], author='', author_email='', url='', @@ -1002,8 +1017,9 @@ The result will be something like: include_package_data=True, zip_safe=False, install_requires=requires, - tests_require=requires, - test_suite="myproject", + extras_require={ + 'testing': testing_extras, + }, entry_points = """\ [paste.app_factory] main = myproject:main @@ -1012,15 +1028,17 @@ The result will be something like: """, ) -Once you've done this, invoking ``$$VENV/bin/python setup.py develop`` will -install a file named ``show_settings`` into the ``$somevirtualenv/bin`` -directory with a small bit of Python code that points to your entry point. It -will be executable. Running it without any arguments will print an error and -exit. Running it with a single argument that is the path of a config file will -print the settings. Running it with an ``--omit=foo`` argument will omit the -settings that have keys that start with ``foo``. Running it with two "omit" -options (e.g., ``--omit=foo --omit=bar``) will omit all settings that have keys -that start with either ``foo`` or ``bar``:: +Once you've done this, invoking ``$VENV/bin/pip install -e .`` will install a +file named ``show_settings`` into the ``$somevirtualenv/bin`` directory with a +small bit of Python code that points to your entry point. It will be +executable. Running it without any arguments will print an error and exit. +Running it with a single argument that is the path of a config file will print +the settings. Running it with an ``--omit=foo`` argument will omit the settings +that have keys that start with ``foo``. Running it with two "omit" options +(e.g., ``--omit=foo --omit=bar``) will omit all settings that have keys that +start with either ``foo`` or ``bar``: + +.. code-block:: bash $ $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar debug_routematch False -- cgit v1.2.3 From 469b5e7276555f5347fdc5dfde938d738920583f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 10 Apr 2016 04:38:52 -0700 Subject: - update extending.rst to use pip --- docs/narr/extending.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index d28eb341d..9dc042024 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -197,8 +197,8 @@ this: elements, such as templates and static assets as necessary. - Install the new package into the same Python environment as the original - application (e.g., ``$VENV/bin/python setup.py develop`` or - ``$VENV/bin/python setup.py install``). + application (e.g., ``$VENV/bin/pip install -e .`` or ``$VENV/bin/pip install + .``). - Change the ``main`` function in the new package's ``__init__.py`` to include the original :app:`Pyramid` application's configuration functions via -- cgit v1.2.3 From ec1bbffae07cd8b573ba007b367b9eec2902a364 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 10 Apr 2016 16:08:38 -0700 Subject: - update installation.rst to use pip, pyvenv, Python 3.4 - simplify installation.rst by removing not-Pyramid things (installing Python and requirements for installing packages) while providing official external references - update cross-reference in quick_tutorial requirements.rst - add glossary entry for pyvenv --- docs/narr/install.rst | 367 +++++++++++++------------------------------------- 1 file changed, 97 insertions(+), 270 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 4a2f228a3..5e2abb236 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -3,14 +3,21 @@ Installing :app:`Pyramid` ========================= +.. note:: + + This installation guide now emphasizes the use of Python 3.4 and greater + for simplicity. + + .. index:: single: install preparation -Before You Install ------------------- +Before You Install Pyramid +-------------------------- -You will need `Python `_ version 2.6 or better to run -:app:`Pyramid`. +Install Python version 3.4 or greater for your operating system, and satisfy +the :ref:`requirements-for-installing-packages`, as described in +the following sections. .. sidebar:: Python Versions @@ -19,15 +26,21 @@ You will need `Python `_ version 2.6 or better to run does not run under any version of Python before 2.6. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, -Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run -on :term:`PyPy` (1.9+). +Mac OS X, and FreeBSD, as well as on Windows platforms. It is also known to +run on :term:`PyPy` (1.9+). -:app:`Pyramid` installation does not require the compilation of any C code, so -you need only a Python interpreter that meets the requirements mentioned. +:app:`Pyramid` installation does not require the compilation of any C code. +However, some :app:`Pyramid` dependencies may attempt to build binary +extensions from C code for performance speed ups. If a compiler or Python +headers are unavailable, the dependency will fall back to using pure Python +instead. -Some :app:`Pyramid` dependencies may attempt to build C extensions for -performance speedups. If a compiler or Python headers are unavailable the -dependency will fall back to using pure Python instead. +.. note:: + + If you see any warnings or errors related to failing to compile the binary + extensions, in most cases you may safely ignore those errors. If you wish to + use the binary extensions, please verify that you have a functioning + compiler and the Python header files installed for your operating system. .. _for-mac-os-x-users: @@ -37,7 +50,7 @@ For Mac OS X Users Python comes pre-installed on Mac OS X, but due to Apple's release cycle, it is often out of date. Unless you have a need for a specific earlier version, it is -recommended to install the latest 2.x or 3.x version of Python. +recommended to install the latest 3.x version of Python. You can install the latest verion of Python for Mac OS X from the binaries on `python.org `_. @@ -46,10 +59,7 @@ Alternatively, you can use the `homebrew `_ package manager. .. code-block:: text - # for python 2.7 - $ brew install python - - # for python 3.5 + # for python 3.x $ brew install python3 If you use an installer for your Python, then you can skip to the section @@ -66,250 +76,101 @@ either install Python using your operating system's package manager *or* you can install Python from source fairly easily on any UNIX system that has development tools. -.. index:: - pair: install; Python (from package, UNIX) - -Package Manager Method -++++++++++++++++++++++ - -You can use your system's "package manager" to install Python. Each package -manager is slightly different, but the "flavor" of them is usually the same. - -For example, on a Debian or Ubuntu system, use the following command: - -.. code-block:: text - - $ sudo apt-get install python2.7-dev - -This command will install both the Python interpreter and its development -header files. Note that the headers are required by some (optional) C -extensions in software depended upon by Pyramid, not by Pyramid itself. - -Once these steps are performed, the Python interpreter will usually be -invokable via ``python2.7`` from a shell prompt. - -.. index:: - pair: install; Python (from source, UNIX) - -Source Compile Method -+++++++++++++++++++++ - -It's useful to use a Python interpreter that *isn't* the "system" Python -interpreter to develop your software. The authors of :app:`Pyramid` tend not -to use the system Python for development purposes; always a self-compiled one. -Compiling Python is usually easy, and often the "system" Python is compiled -with options that aren't optimal for web development. For an explanation, see -https://github.com/Pylons/pyramid/issues/747. - -To compile software on your UNIX system, typically you need development tools. -Often these can be installed via the package manager. For example, this works -to do so on an Ubuntu Linux system: - -.. code-block:: text - - $ sudo apt-get install build-essential +.. seealso:: See the official Python documentation :ref:`Using Python on Unix + platforms ` for full details. -On Mac OS X, installing `XCode `_ has -much the same effect. - -Once you've got development tools installed on your system, you can install a -Python 2.7 interpreter from *source*, on the same system, using the following -commands: - -.. code-block:: text - - $ cd ~ - $ mkdir tmp - $ mkdir opt - $ cd tmp - $ wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz - $ tar xvzf Python-2.7.3.tgz - $ cd Python-2.7.3 - $ ./configure --prefix=$HOME/opt/Python-2.7.3 - $ make && make install - -Once these steps are performed, the Python interpreter will be invokable via -``$HOME/opt/Python-2.7.3/bin/python`` from a shell prompt. .. index:: pair: install; Python (from package, Windows) +.. _if-you-don-t-yet-have-a-python-interpreter-windows: + 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 2.7-series interpreter executable from +install it by downloading a Python 3.x-series interpreter executable from `python.org's download section `_ (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. -.. warning:: - - After you install Python on Windows, you may need to add the ``C:\Python27`` - directory to your environment's ``Path`` in order to make it possible to - invoke Python from a command prompt by typing ``python``. To do so, right - click ``My Computer``, select ``Properties`` --> ``Advanced Tab`` --> - ``Environment Variables`` and add that directory to the end of the ``Path`` - environment variable. - -.. index:: - single: installing on UNIX - -.. _installing_unix: - -Installing :app:`Pyramid` on a UNIX System ------------------------------------------- - -It is best practice to install :app:`Pyramid` into a "virtual" Python -environment in order to obtain isolation from any "system" packages you've got -installed in your Python version. This can be done by using the -:term:`virtualenv` package. Using a virtualenv will also prevent -:app:`Pyramid` from globally installing versions of packages that are not -compatible with your system Python. - -To set up a virtualenv in which to install :app:`Pyramid`, first ensure that -:term:`setuptools` is installed. To do so, invoke ``import setuptools`` within -the Python interpreter you'd like to run :app:`Pyramid` under. - -The following command will not display anything if setuptools is already -installed: - -.. code-block:: text - - $ python2.7 -c 'import setuptools' - -Running the same command will yield the following output if setuptools is not -yet installed: - -.. code-block:: text +.. seealso:: See the official Python documentation :ref:`Using Python on + Windows ` for full details. - Traceback (most recent call last): - File "", line 1, in - ImportError: No module named setuptools - -If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools manually. - -If you are using a "system" Python (one installed by your OS distributor or a -third-party packager such as Fink or MacPorts), you can usually install the -setuptools package by using your system's package manager. If you cannot do -this, or if you're using a self-installed version of Python, you will need to -install setuptools "by hand". Installing setuptools "by hand" is always a -reasonable thing to do, even if your package manager already has a pre-chewed -version of setuptools for installation. - -Installing Setuptools -~~~~~~~~~~~~~~~~~~~~~ - -To install setuptools by hand under Python 2, first download `ez_setup.py -`_ then invoke -it using the Python interpreter into which you want to install setuptools. - -.. code-block:: text +.. seealso:: Download and install the `Python for Windows extensions + `_. 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. - $ python ez_setup.py +.. warning:: -Once this command is invoked, setuptools should be installed on your system. -If the command fails due to permission errors, you may need to be the -administrative user on your system to successfully invoke the script. To -remediate this, you may need to do: + After you install Python on Windows, you may need to add the ``C:\Python3x`` + directory to your environment's ``Path``, where ``x`` is the minor version + of installed Python, in order to make it possible to invoke Python from a + command prompt by typing ``python``. To do so, right click ``My Computer``, + select ``Properties`` --> ``Advanced Tab`` --> ``Environment Variables`` and + add that directory to the end of the ``Path`` environment variable. -.. code-block:: text + .. seealso:: See `Configuring Python (on Windows) + `_ for + full details. - $ sudo python ez_setup.py .. index:: - pair: install; virtualenv + single: requirements for installing packages -Installing the ``virtualenv`` Package -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _requirements-for-installing-packages: -Once you've got setuptools installed, you should install the :term:`virtualenv` -package. To install the :term:`virtualenv` package into your -setuptools-enabled Python interpreter, use the ``easy_install`` command. +Requirements for Installing Packages +------------------------------------ -.. warning:: +Use :term:`pip` for installing packages and :term:`pyvenv` for creating a +virtual environment. A virtual environment is a semi-isolated Python +environment that allows packages to be installed for use by a particular +application, rather than being installed system wide. - Python 3.3 includes ``pyvenv`` out of the box, which provides similar - functionality to ``virtualenv``. We however suggest using ``virtualenv`` - instead, which works well with Python 3.3. This isn't a recommendation made - for technical reasons; it's made because it's not feasible for the authors - of this guide to explain setup using multiple virtual environment systems. - We are aiming to not need to make the installation documentation - Turing-complete. +.. seealso:: See the Python Packaging Authority's (PyPA) documention + `Requirements for Installing Packages + `_ + for full details. - If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``setuptools`` into the virtual environment manually, which - this guide does not cover. - -.. code-block:: text - - $ easy_install virtualenv - -This command should succeed, and tell you that the virtualenv package is now -installed. If it fails due to permission errors, you may need to install it as -your system's administrative user. For example: - -.. code-block:: text - - $ sudo easy_install virtualenv .. index:: - single: virtualenv - pair: Python; virtual environment - -Creating the Virtual Python Environment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Once the :term:`virtualenv` package is installed in your Python environment, -you can then create a virtual environment. To do so, invoke the following: - -.. code-block:: text - - $ export VENV=~/env - $ virtualenv $VENV - New python executable in /home/foo/env/bin/python - Installing setuptools.............done. - -You can either follow the use of the environment variable, ``$VENV``, or -replace it with the root directory of the :term:`virtualenv`. In that case, the -`export` command can be skipped. If you choose the former approach, ensure that -it's an absolute path. + single: installing on UNIX + single: installing on Mac OS X -.. warning:: +.. _installing_unix: - Avoid using the ``--system-site-packages`` option when creating the - virtualenv unless you know what you are doing. For versions of virtualenv - prior to 1.7, make sure to use the ``--no-site-packages`` option, because - this option was formerly not the default and may produce undesirable - results. +Installing :app:`Pyramid` on a UNIX System +------------------------------------------ -.. warning:: +After installing Python as described previously in :ref:`for-mac-os-x-users` or +:ref:`if-you-don-t-yet-have-a-python-interpreter-unix`, and satisfying the +:ref:`requirements-for-installing-packages`, you can now install Pyramid. - *do not* use ``sudo`` to run the ``virtualenv`` script. It's perfectly - acceptable (and desirable) to create a virtualenv as a normal user. +#. Make a :term:`virtualenv` workspace: + .. code-block:: bash -Installing :app:`Pyramid` into the Virtual Python Environment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + $ export VENV=~/env + $ pyvenv $VENV -After you've got your virtualenv installed, you may install :app:`Pyramid` -itself using the following commands: + You can either follow the use of the environment variable ``$VENV``, or + replace it with the root directory of the virtual environment. If you choose + the former approach, ensure that ``$VENV`` is an absolute path. In the + latter case, the ``export`` command can be skipped. -.. parsed-literal:: +#. (Optional) Consider using ``$VENV/bin/activate`` to make your shell + environment wired to use the virtual environment. - $ $VENV/bin/easy_install "pyramid==\ |release|\ " +#. Use ``pip`` to get :app:`Pyramid` and its direct dependencies installed: -The ``easy_install`` command will take longer than the previous ones to -complete, as it downloads and installs a number of dependencies. + .. parsed-literal:: -.. note:: + $ $VENV/bin/pip install "pyramid==\ |release|\ " - If you see any warnings and/or errors related to failing to compile the C - extensions, in most cases you may safely ignore those errors. If you wish to - use the C extensions, please verify that you have a functioning compiler and - the Python header files installed. .. index:: single: installing on Windows @@ -319,72 +180,38 @@ complete, as it downloads and installs a number of dependencies. Installing :app:`Pyramid` on a Windows System --------------------------------------------- -You can use Pyramid on Windows under Python 2 or 3. - -#. Download and install the most recent `Python 2.7.x or 3.3.x version - `_ for your system. - -#. Download and install the `Python for Windows extensions - `_. 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. - -#. Install latest :term:`setuptools` distribution into the Python from step 1 - above: download `ez_setup.py - `_ and run - it using the ``python`` interpreter of your Python 2.7 or 3.3 installation - using a command prompt: - - .. code-block:: text - - # modify the command according to the python version, e.g.: - # for Python 2.7: - c:\> c:\Python27\python ez_setup.py - # for Python 3.3: - c:\> c:\Python33\python ez_setup.py - -#. Install `virtualenv`: - - .. code-block:: text - - # modify the command according to the python version, e.g.: - # for Python 2.7: - c:\> c:\Python27\Scripts\easy_install virtualenv - # for Python 3.3: - c:\> c:\Python33\Scripts\easy_install virtualenv +After installing Python as described previously in +:ref:`if-you-don-t-yet-have-a-python-interpreter-windows`, and satisfying the +:ref:`requirements-for-installing-packages`, you can now install Pyramid. #. Make a :term:`virtualenv` workspace: - .. code-block:: text + .. code-block:: ps1con c:\> set VENV=c:\env - # modify the command according to the python version, e.g.: - # for Python 2.7: - c:\> c:\Python27\Scripts\virtualenv %VENV% - # for Python 3.3: - c:\> c:\Python33\Scripts\virtualenv %VENV% + # replace "x" with your minor version of Python 3 + c:\> c:\Python3x\Scripts\pyvenv %VENV% - You can either follow the use of the environment variable, ``%VENV%``, or - replace it with the root directory of the :term:`virtualenv`. In that case, - the `set` command can be skipped. If you choose the former approach, ensure - that it's an absolute path. + You can either follow the use of the environment variable ``%VENV%``, or + replace it with the root directory of the virtual environment. If you choose + the former approach, ensure that ``%VENV%`` is an absolute path. In the + latter case, the ``set`` command can be skipped. #. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell - environment wired to use the virtualenv. + environment wired to use the virtual environment. -#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies - installed: +#. Use ``pip`` to get :app:`Pyramid` and its direct dependencies installed: .. parsed-literal:: - c:\\env> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ " + c:\\env> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " + What Gets Installed ------------------- -When you ``easy_install`` :app:`Pyramid`, various other libraries such as -WebOb, PasteDeploy, and others are installed. +When you install :app:`Pyramid`, various libraries such as WebOb, PasteDeploy, +and others are installed. Additionally, as chronicled in :ref:`project_narr`, scaffolds will be registered, which make it easy to start a new :app:`Pyramid` project. -- cgit v1.2.3 From 9e9fa9ac40bdd79fbce69f94a13d705e40f3d458 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 22 Mar 2016 01:02:05 -0500 Subject: add a csrf_view to the view pipeline supporting a require_csrf option --- docs/narr/hooks.rst | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2c3782387..e7db97565 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1580,6 +1580,11 @@ There are several built-in view derivers that :app:`Pyramid` will automatically apply to any view. Below they are defined in order from furthest to closest to 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 ``require_csrf`` is not defined. + ``secured_view`` Enforce the ``permission`` defined on the view. This element is a no-op if no @@ -1656,27 +1661,32 @@ View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what to do, and they have a chance to affect every view in the application. -Let's look at one more example which will protect views by requiring a CSRF -token unless ``disable_csrf=True`` is passed to the view: +Let's override the default CSRF checker to default to on instead of off and +only check ``POST`` requests: .. code-block:: python :linenos: from pyramid.response import Response from pyramid.session import check_csrf_token + from pyramid.viewderivers import INGRESS - def require_csrf_view(view, info): + def csrf_view(view, info): + val = info.options.get('require_csrf', True) wrapper_view = view - if not info.options.get('disable_csrf', False): - def wrapper_view(context, request): + if val: + if val is True: + val = 'csrf_token' + def csrf_view(context, request): if request.method == 'POST': - check_csrf_token(request) + check_csrf_token(request, val, raises=True) return view(context, request) + wrapper_view = csrf_view return wrapper_view - require_csrf_view.options = ('disable_csrf',) + csrf_view.options = ('require_csrf',) - config.add_view_deriver(require_csrf_view) + config.add_view_deriver(csrf_view, 'csrf_view', over='secured_view', under=INGRESS) def protected_view(request): return Response('protected') @@ -1685,7 +1695,7 @@ token unless ``disable_csrf=True`` is passed to the view: return Response('unprotected') config.add_view(protected_view, name='safe') - config.add_view(unprotected_view, name='unsafe', disable_csrf=True) + config.add_view(unprotected_view, name='unsafe', require_csrf=False) Navigating to ``/safe`` with a POST request will then fail when the call to :func:`pyramid.session.check_csrf_token` raises a -- cgit v1.2.3 From 6b35eb6ca3b271e2943d37307c925c5733e082d9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 10 Apr 2016 20:50:10 -0500 Subject: rewrite csrf checks to support a global setting to turn it on - only check csrf on POST - support "pyramid.require_default_csrf" setting - support "require_csrf=True" to fallback to the global setting to determine the token name --- docs/narr/hooks.rst | 52 ++++++-------------------------------------------- docs/narr/sessions.rst | 42 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 48 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index e7db97565..28d1e09d5 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1580,11 +1580,6 @@ There are several built-in view derivers that :app:`Pyramid` will automatically apply to any view. Below they are defined in order from furthest to closest to 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 ``require_csrf`` is not defined. - ``secured_view`` Enforce the ``permission`` defined on the view. This element is a no-op if no @@ -1595,6 +1590,12 @@ the user-defined :term:`view callable`: This element will also output useful debugging information when ``pyramid.debug_authorization`` is enabled. +``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. + ``owrapped_view`` Invokes the wrapped view defined by the ``wrapper`` option. @@ -1661,47 +1662,6 @@ View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what to do, and they have a chance to affect every view in the application. -Let's override the default CSRF checker to default to on instead of off and -only check ``POST`` requests: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - from pyramid.session import check_csrf_token - from pyramid.viewderivers import INGRESS - - def csrf_view(view, info): - val = info.options.get('require_csrf', True) - wrapper_view = view - if val: - if val is True: - val = 'csrf_token' - def csrf_view(context, request): - if request.method == 'POST': - check_csrf_token(request, val, raises=True) - return view(context, request) - wrapper_view = csrf_view - return wrapper_view - - csrf_view.options = ('require_csrf',) - - config.add_view_deriver(csrf_view, 'csrf_view', over='secured_view', under=INGRESS) - - def protected_view(request): - return Response('protected') - - def unprotected_view(request): - return Response('unprotected') - - config.add_view(protected_view, name='safe') - config.add_view(unprotected_view, name='unsafe', require_csrf=False) - -Navigating to ``/safe`` with a POST request will then fail when the call to -:func:`pyramid.session.check_csrf_token` raises a -:class:`pyramid.exceptions.BadCSRFToken` exception. However, ``/unsafe`` will -not error. - Ordering View Derivers ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index db554a93b..3baed1cb8 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -389,8 +389,43 @@ header named ``X-CSRF-Token``. # ... -.. index:: - single: session.new_csrf_token +.. _auto_csrf_checking: + +Checking CSRF Tokens Automatically +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.7 + +:app:`Pyramid` supports automatically checking CSRF tokens on POST requests. +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 POST 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.params`` which is a combination of the +query string and a 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. + +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`` +resposne being sent to the client. Checking CSRF Tokens with a View Predicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -411,6 +446,9 @@ include ``check_csrf=True`` as a view predicate. See instead of ``HTTPBadRequest``, so ``check_csrf=True`` behavior is different from calling :func:`pyramid.session.check_csrf_token`. +.. index:: + single: session.new_csrf_token + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 15b97dc81c8bcdc039f8f2293f85812f68a076da Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 10 Apr 2016 20:51:23 -0500 Subject: deprecate the check_csrf predicate --- docs/narr/sessions.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 3baed1cb8..4e8f6db88 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -430,6 +430,10 @@ resposne being sent to the client. Checking CSRF Tokens with a View Predicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. deprecated:: 1.7 + Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead + to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. + A convenient way to require a valid CSRF token for a particular view is to include ``check_csrf=True`` as a view predicate. See :meth:`pyramid.config.Configurator.add_view`. -- cgit v1.2.3 From 769da1215a0287f4161e58f36d8d4b7650154202 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 10 Apr 2016 21:14:22 -0500 Subject: cleanup some references in the docs --- docs/narr/sessions.rst | 32 ++++++++++++++++---------------- docs/narr/viewconfig.rst | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 4e8f6db88..d66e86258 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -367,6 +367,21 @@ Or include it as a header in a jQuery AJAX request: The handler for the URL that receives the request should then require that the correct CSRF token is supplied. +.. index:: + single: session.new_csrf_token + +Using the ``session.new_csrf_token`` Method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To explicitly create a new CSRF token, use the ``session.new_csrf_token()`` +method. This differs only from ``session.get_csrf_token()`` inasmuch as it +clears any existing CSRF token, creates a new CSRF token, sets the token into +the session, and returns the token. + +.. code-block:: python + + token = request.session.new_csrf_token() + Checking CSRF Tokens Manually ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -425,7 +440,7 @@ performing CSRF checking manually. 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`` -resposne being sent to the client. +response being sent to the client. Checking CSRF Tokens with a View Predicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -449,18 +464,3 @@ include ``check_csrf=True`` as a view predicate. See predicate system, when it doesn't find a view, raises ``HTTPNotFound`` instead of ``HTTPBadRequest``, so ``check_csrf=True`` behavior is different from calling :func:`pyramid.session.check_csrf_token`. - -.. index:: - single: session.new_csrf_token - -Using the ``session.new_csrf_token`` Method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To explicitly create a new CSRF token, use the ``session.new_csrf_token()`` -method. This differs only from ``session.get_csrf_token()`` inasmuch as it -clears any existing CSRF token, creates a new CSRF token, sets the token into -the session, and returns the token. - -.. code-block:: python - - token = request.session.new_csrf_token() diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 0bd52b6e2..e645185f5 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -192,6 +192,32 @@ Non-Predicate Arguments only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with the first element of ``None``, i.e., ``(None, {'public':True})``. + +``require_csrf`` + + CSRF checks only affect POST requests. Any other request methods will pass + untouched. This option is used in combination with the + ``pyramid.require_default_csrf`` setting to control which request parameters + are checked for CSRF tokens. + + This feature requires a configured :term:`session factory`. + + If this option is set to ``True`` then CSRF checks will be enabled for POST + requests to this view. The required token will be whatever was specified by + the ``pyramid.require_default_csrf`` setting, or will fallback to + ``csrf_token``. + + If this option is set to a string then CSRF checks will be enabled and it + will be used as the required token regardless of the + ``pyramid.require_default_csrf`` setting. + + If this option is set to ``False`` then CSRF checks will be disabled + regardless of the ``pyramid.require_default_csrf`` setting. + + See :ref:`auto_csrf_checking` for more information. + + .. versionadded:: 1.7 + ``wrapper`` The :term:`view name` of a different :term:`view configuration` which will receive the response body of this view as the ``request.wrapped_body`` -- cgit v1.2.3 From 5b918737fb361584d820893fc82c6b898ae1fc69 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 10 Apr 2016 22:18:21 -0600 Subject: Update router documentation --- docs/narr/router.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index e02142e6e..d4c0cc885 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -46,16 +46,22 @@ request enters a :app:`Pyramid` application through to the point that object. The former contains a dictionary representing the matched dynamic elements of the request's ``PATH_INFO`` value, and the latter contains the :class:`~pyramid.interfaces.IRoute` object representing the route which - matched. The root object associated with the route found is also generated: + matched. + + A :class:`~pyramid.events.BeforeTraversal` :term:`event` is sent to any + subscribers. + + The root object associated with the route found is also generated: if the :term:`route configuration` which matched has an associated ``factory`` argument, this factory is used to generate the root object, otherwise a default :term:`root factory` is used. #. If a route match was *not* found, and a ``root_factory`` argument was passed to the :term:`Configurator` constructor, that callable is used to generate - the root object. If the ``root_factory`` argument passed to the - Configurator constructor was ``None``, a default root factory is used to - generate a root object. + the root object after a :class:`~pyramid.events.BeforeTraversal` + :term:`event` is sent to any subscribers. If the ``root_factory`` argument + passed to the Configurator constructor was ``None``, a default root factory + is used to generate a root object. #. The :app:`Pyramid` router calls a "traverser" function with the root object and the request. The traverser function attempts to traverse the root -- cgit v1.2.3 From f21b2bf0465593f3831bc1d25ef14bed9f0c6fd5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 11 Apr 2016 01:44:05 -0700 Subject: - update narr/project.rst to use pip instead of setup.py - update starter scaffold tests and setup.py (used in `narr/project.rst` and `narr/testing.rst`) - update links to documentation --- docs/narr/MyProject/development.ini | 4 +- .../MyProject/myproject/templates/mytemplate.pt | 6 +- docs/narr/MyProject/myproject/tests.py | 2 +- docs/narr/MyProject/production.ini | 4 +- docs/narr/MyProject/setup.py | 21 ++- docs/narr/project.rst | 146 +++++++++------------ 6 files changed, 84 insertions(+), 99 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 749e574eb..94fece8ce 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html ### [app:main] @@ -29,7 +29,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html ### [loggers] diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 65d7f0609..543663fe8 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -34,15 +34,15 @@

Pyramid Starter scaffold

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework 1.6b2.

+

Welcome to ${project}, an application generated by
the Pyramid Web Framework 1.7.